Commit Graph

131 Commits

Author SHA1 Message Date
Siavash Sameni
5764719375 v0.0.38: FC-P4 complete — session versioning, wire envelope, auto-backup
FC-P4-T1: Session State Versioning
- RatchetState serialize/deserialize with [MAGIC:0xFC][VERSION:1][bincode]
- Legacy (raw bincode) still loads — backward compatible
- Client + WASM both use versioned format
- 2 new tests: roundtrip + legacy compat

FC-P4-T2: WireMessage Versioning Envelope
- Format: [WZ magic][version:u8][length:u32 BE][bincode payload]
- Server + client + WASM accept both envelope and legacy on receive
- Client still sends raw bincode (server handles both)
- Future version → "update required" error instead of crash
- 3 new tests: roundtrip, legacy compat, future version rejection

FC-P4-T3: Periodic Auto-Backup
- Every 5 minutes, encrypts sessions+contacts+sender_keys to ~/.warzone/backups/
- HKDF-derived key from seed, ChaCha20-Poly1305 AEAD
- Atomic writes (temp file + rename), rotates to keep last 3
- /backup command for manual trigger

127 tests passing (was 122)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 17:03:02 +04:00
Siavash Sameni
a368ab24d2 v0.0.37: TUI call state UI, missed calls, inline keyboards in web
FC-P2-T4: TUI call state machine
- CallInfo struct + CallPhase enum (Calling/Ringing/Active)
- Header shows call indicator: yellow "Calling...", magenta "Incoming", green timer
- /call sets Calling, /accept sets Active, /reject+/hangup clears
- Incoming signals show contextual messages (Offer→prompt, Answer→connected, etc.)

FC-P2-T5: Missed call display in TUI
- WS Text frames parsed for missed_call + bot_message JSON
- Missed calls: "📞 Missed call from X at HH:MM" + terminal bell
- Bot messages rendered as @botname: text

FC-P8-T5: Inline keyboard buttons in web
- CSS styled keyboard buttons (.kbd-btn)
- Bot messages with reply_markup render clickable button rows
- Click sends callback_data back to bot as bot_message
- Works in both WS text handler and handleIncomingMessage fallback

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 16:44:14 +04:00
Siavash Sameni
3429f518b1 feat: TUI /call, /accept, /reject, /hangup commands (FC-P2-T1+T2+T3)
- /call [fp|@alias|0x...] — send CallSignal::Offer to peer
- /accept — answer incoming call (uses last_dm_peer)
- /reject — reject incoming call
- /hangup — end active call
- All four added to /help text

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 16:19:01 +04:00
Siavash Sameni
e9182fdb41 v0.0.36: web call UI — call/accept/reject/hangup with signaling
Web client:
- Call bar between header and messages (hidden when idle)
- Call button appears when peer is set (not group)
- Incoming call: pulsing notification + Accept/Reject buttons
- Call states: idle → calling → ringing → active
- /call, /accept, /reject, /hangup slash commands
- CallSignal sent via WS binary frames (same as messages)
- handleCallSignal processes Offer/Answer/Hangup/Reject/Ringing/Busy
- Vibration on incoming call (mobile)
- create_call_signal WASM import wired up

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 16:07:03 +04:00
Siavash Sameni
0b58ddcee5 v0.0.35: WASM create_call_signal, selectable identity, web sections
FC-P3-T2: WASM create_call_signal() export
- Accepts signal_type string (offer/answer/hangup/etc), payload, target
- Returns bincode WireMessage::CallSignal bytes for WS send

FC-P3-T9: Selectable identity display in web
- ETH address shown in code-style block, click to copy
- addSys() gains rawHtml parameter for rich content

FC-P3-T5: Section navigation comments in web.rs
- 5 section markers: State, Crypto, Network, UI, Commands

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 16:00:43 +04:00
Siavash Sameni
0e7277fb20 fix: visible scrollbar on web messages area
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 15:51:43 +04:00
Siavash Sameni
7628ff7a75 v0.0.34: fix bot sendMessage — store per-bot numeric ID reverse mapping
Per-bot numeric IDs (privacy feature) broke sendMessage because the
reverse lookup couldn't find the fingerprint from the per-bot hash.

Fix: store numid:<numeric_id> → fingerprint in tokens tree when
generating updates. resolve_chat_id checks this mapping first.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 15:35:52 +04:00
Siavash Sameni
3489a7cf74 fix: log full bot tokens + write to data_dir/bot-tokens.txt
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 15:05:11 +04:00
Siavash Sameni
1e47b888c8 v0.0.33: bump version
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 14:51:39 +04:00
Siavash Sameni
5415d1f5c8 fix: auto-join #ops creates group if missing, remove auth from create/join group
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 14:47:54 +04:00
Siavash Sameni
13f2227bf0 v0.0.32: system bots config — persist across data wipes, welcome screen
Server:
- --bots-config <path> loads JSON array of system bots on startup
- Bots auto-created if missing, aliases restored on every start
- Bot list stored in DB for welcome screen (system:bot_list key)
- GET /v1/bot/list returns system bots (public, no auth)

Welcome screen:
- Web + TUI show available bots on first login
- "Available bots: @helpbot — featherChat help, @codebot — Coding..."
- Clickable in web (via address detection)

Config: bots.example.json with 10 suggested bots
Usage: warzone-server --enable-bots --bots-config bots.json

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 14:07:34 +04:00
Siavash Sameni
f04c24187d feat: auto-join #ops on first login (web + TUI)
New users with no peer/group set automatically join #ops so they
have someone to talk to. Saved peer overrides this on subsequent visits.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:54:19 +04:00
Siavash Sameni
3e583bb04b v0.0.31: per-bot unique user IDs, remove raw fingerprint from bot API
Privacy: from.id is now Hash(bot_token + user_fp) → different bots see
different numeric IDs for the same user. Prevents cross-bot user correlation.

Removed id_str (raw hex fingerprint) from all bot API responses.
Updated LLM_BOT_DEV.md and LLM_HELP.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 13:49:10 +04:00
Siavash Sameni
6fee73fc4d v0.0.30: markdown rendering in web, fix scrolling
Web:
- Markdown renderer: **bold**, *italic*, `code`, ```code blocks```,
  # headers, [links](url), > blockquotes, - lists
- All message text rendered as markdown (bot messages look great now)
- Fixed scroll: overflow-y: scroll + min-height: 0 on messages container
- CSS for code blocks, pre, headers, blockquotes, lists
- Styled: code=cyan bg, pre=dark bg+border, bold=white, italic=amber

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 12:36:00 +04:00
Siavash Sameni
8b37bd4323 fix: getUpdates enforces min 1s delay when empty (prevents tight-loop spam)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 12:25:41 +04:00
Siavash Sameni
b0fa9f92bd fix: BotFather stores rec: AliasRecord so resolve_alias finds bot aliases
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 12:21:45 +04:00
Siavash Sameni
4118be7ef3 docs: update LLM bot dev guide with BotFather chat flow + plaintext auto-detect
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:27:13 +04:00
Siavash Sameni
76fd8dd81a fix: web bot detection checks alias name first, then whois fallback
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:19:34 +04:00
Siavash Sameni
e0e747e005 fix: BotFather fingerprint uses all-hex (00000000000000000b0ffa00e000000f)
Old fp contained non-hex chars (o,r) which got stripped by normFP,
causing whois lookup failure and bot detection to miss.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:17:05 +04:00
Siavash Sameni
76ee2ab585 fix: BotFather alias record ensures resolve_alias works after data wipe
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:14:41 +04:00
Siavash Sameni
878847ce89 fix: recognize @botfather as bot peer (special case, not pattern change)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:11:28 +04:00
Siavash Sameni
362e7a765b v0.0.29: BotFather — create bots by messaging @botfather
Built-in BotFather (Rust, server-side):
- Intercepts messages to @botfather in deliver_or_queue
- Commands: /newbot <name>, /mybots, /deletebot <name>, /token <name>
- Creates bot with fingerprint, token, alias, tracks ownership
- Replies via push_to_client or queue (works offline)
- Only active when --enable-bots is set

Standalone BotFather (Python):
- tools/botfather.py: uses bot API (getUpdates/sendMessage)
- Delegates core ops to built-in handler
- Extensible for additional features
- Reads token from BOTFATHER_TOKEN env or .botfather_token file

Flow: User messages @botfather → "/newbot MyBot" → gets token back

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 11:08:35 +04:00
Siavash Sameni
9dd7341809 fix: build-bleeding uses fedora-43
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 10:06:10 +04:00
Siavash Sameni
6196057f3e feat: build-bleeding.sh — Arch Linux Docker on Fedora VM for bleeding edge builds
VM: fc-bleeding (Fedora 41), Build: archlinux:latest Docker container
Output: target/linux-x86_64-bleeding/
No conflict with fc-builder (build-linux.sh)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 10:04:31 +04:00
Siavash Sameni
76cac77259 v0.0.28: BotFather-only registration, per-instance bot toggle, docs update
Security:
- Bot registration restricted to BotFather (requires botfather_token)
- Direct POST /v1/bot/register without BotFather auth → rejected

Deploy:
- systemd service reads /home/warzone/server.env for EXTRA_ARGS
- deploy/warzone-server.env.mequ: no bots (default)
- deploy/warzone-server.env.kh3rad3ree: --enable-bots
- setup.sh copies per-hostname env file

Docs updated:
- LLM_HELP.md: BotFather flow, plaintext bot messaging, E2E option, bridge
- LLM_BOT_DEV.md: botfather_token requirement, E2E mode, bridge section
- BOT_API.md: full BotFather flow, ownership, numeric IDs, webhook delivery
- SERVER.md: --enable-bots flag, per-instance config, bot system section
- USAGE.md: bot messaging, BotFather, bridge tool

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:52:12 +04:00
Siavash Sameni
8603087afb v0.0.27: TG-compatible bots — plaintext send, numeric IDs, webhooks, BotFather
Bot compatibility:
- Clients send plaintext bot_message to bot aliases (no E2E encryption)
- Numeric chat_id: fp_to_numeric_id() deterministic hash, accept string/number
- Webhook delivery: POST updates to bot's webhook URL (async, fire-and-forget)
- getUpdates timeout raised to 50s (was 30, TG uses 50)
- parse_mode HTML rendered in web client
- E2E bot registration: optional seed + bundle for encrypted bot sessions

BotFather + instance control:
- --enable-bots CLI flag (default: disabled)
- BotFather auto-created on first start (@botfather alias)
- Bot ownership: owner fingerprint stored in bot_info
- All bot endpoints return 403 when disabled

Bot Bridge:
- tools/bot-bridge.py: TG-compatible proxy for unmodified TG bots
- Translates chat_id int↔string, proxies getUpdates/sendMessage
- README with python-telegram-bot and Telegraf examples

Test fixes:
- Updated tests for ETH address display in header/messages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:45:45 +04:00
Siavash Sameni
067f1ea20b v0.0.25: fix text selection in web chat, don't steal focus when selecting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:15:40 +04:00
Siavash Sameni
b9e7b3e05c fix: arch linux uses rustup for wasm target support
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:12:09 +04:00
Siavash Sameni
deb220ff2c fix: SW uses network-first strategy, updates apply without clearing storage
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:11:15 +04:00
Siavash Sameni
0697c988fa fix: build-linux.sh --local cd to project root before building
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:06:29 +04:00
Siavash Sameni
1851728a09 v0.0.24: ETH display in TUI header/messages, web peer resolve, click-focus
TUI:
- Header shows peer ETH address (resolved on /peer set)
- Own messages show ETH format
- Resolve display shows full formatted fingerprint (xxxx:xxxx:...)
- peer_eth field stored on App for header display

Web:
- Pasting 0x address in peer input box now resolves via /v1/resolve/
- Send path resolves 0x/@ before encrypting
- Click messages area → focuses text input
- Own messages show ETH format

Version: 0.0.23 → 0.0.24, SW cache wz-v4 → wz-v5
Build script: --local, --local-ship, --local-clean commands

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 09:04:37 +04:00
Siavash Sameni
ea04405199 v0.0.23: ETH display everywhere, local build, web UX fixes
Version: 0.0.22 → 0.0.23, SW cache wz-v3 → wz-v4

TUI:
- Own messages show ETH address (0x...) instead of fingerprint
- Received messages: async ETH cache lookup (resolve on first sight)
- /info shows Identity + Fingerprint
- Welcome message shows ETH address

Web:
- Header shows only ETH address (single element, click to copy)
- Own messages show ETH format
- Received messages resolve sender ETH via /v1/resolve/
- /peer 0x... resolves via /v1/resolve/ endpoint
- Click messages area → focuses text input

Client:
- register_bundle sends eth_address to server
- ETH↔fingerprint mapping stored on registration

Build:
- --local: build on current machine (auto-detect apt/dnf/pacman/brew)
- --local-ship: build locally + deploy to all servers
- --local-clean: build + clean cargo cache

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 08:50:31 +04:00
Siavash Sameni
2aa58a4319 fix: TUI shows ETH address, /peer 0x... resolves, Cmd+key on macOS
TUI header: shows ETH address (0x...) instead of fingerprint
/peer 0x...: resolves via GET /v1/resolve/:address endpoint
Cmd+A/E/U/K/W: macOS SUPER modifier now handled alongside CONTROL
Added resolve_address() method for ETH/any address resolution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 08:20:38 +04:00
Siavash Sameni
3efce2ddf4 v0.0.22: version bump, ETH identity in web client, version bump rule
Version:
- Workspace + protocol: 0.0.21 → 0.0.22
- Web client VERSION: 0.0.17 → 0.0.22
- Service worker cache: wz-v2 → wz-v3

ETH identity:
- Added WasmIdentity::eth_address() export (derives from seed via secp256k1)
- Web client sends eth_address during key registration
- Identity display shows ETH address first, then fingerprint
- No more server-side resolve needed — computed client-side

CLAUDE.md:
- Added MANDATORY version bump rule (4 places to update)
- Must bump on every functional change, never skip SW cache

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 08:11:31 +04:00
Siavash Sameni
fcbf2d5859 feat: complete Telegram-compatible Bot API + bot dev guide
Bot API (routes/bot.rs — full rewrite):
- getUpdates: persistent update_id counter, offset acknowledgement,
  limit (max 100), long-poll up to 30s with 1s intervals
- sendMessage: parse_mode, reply_to_message_id, reply_markup (inline keyboards)
- answerCallbackQuery: acknowledge button clicks
- editMessageText: update sent messages
- setWebhook / deleteWebhook / getWebhookInfo: webhook configuration
- sendDocument: file reference with caption
- Bot queue: raw messages migrated to bot_queue:<fp>:<update_id> for ordering

Web client (routes/web.rs):
- Bot messages rendered properly (was showing "[message could not be decrypted]")
- Handles bot_message, bot_edit, bot_document as both Text and Binary WS frames
- Inline keyboard buttons rendered as bracketed text
- Missed call notifications handled in Text frame path

Docs:
- LLM_BOT_DEV.md: token-optimized bot dev reference for coding assistant LLM
  (Python + Node.js examples, all endpoints, TG compatibility table)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 07:50:14 +04:00
Siavash Sameni
953b3bd13a docs: CLAUDE.md design principles, update ARCHITECTURE + SECURITY
- CLAUDE.md: design principles (E2E by default, semi-trusted server,
  federation transparency, TG bot compat), coding conventions for Rust/TUI/
  WASM/federation/bots, task naming, key files reference
- ARCHITECTURE.md: added bots to high-level diagram, friends/bot/resolve
  modules, 9 sled trees (was 7), bot API sequence diagram, addressing table,
  federated features table, test count 72→122
- SECURITY.md: v0.0.21, added friend list/API auth/device/bot alias to
  protected assets, auth & authorization section, rate limiting, session recovery

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 07:39:30 +04:00
Siavash Sameni
210fbbb35b feat: bot alias reservation + BOT_API.md documentation
- Aliases ending with Bot/bot/_bot reserved for registered bots only
- Non-bot users get clear error directing to /v1/bot/register
- Bot registration auto-creates alias (@name_bot suffix)
- BOT_API.md: full developer guide with endpoints, examples, echo bot
- LLM_HELP.md: expanded bot section with update types + Python example

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 07:34:45 +04:00
Siavash Sameni
7b72f7cba5 feat: friend list, bot API, ETH addressing, deep links, docs overhaul
Tier 1 — New features:
- E2E encrypted friend list: server stores opaque blob (POST/GET /v1/friends),
  protocol-level encrypt/decrypt with HKDF-derived key, 4 tests
- Telegram Bot API compatibility: /bot/register, /bot/:token/getUpdates,
  sendMessage, getMe — TG-style Update objects with proper message mapping
- ETH address resolution: GET /v1/resolve/:address (0x.../alias/@.../fp),
  bidirectional ETH↔fp mapping stored on key registration
- Seed recovery: /seed command in TUI + web client
- URL deep links: /message/@alias, /message/0xABC, /group/#ops
- Group members with online status in GET /groups/:name/members

Tier 2 — UX polish:
- TUI: /friend, /friend <addr>, /unfriend <addr> with presence checking
- Web: friend commands, showGroupMembers() on group join
- Web: ETH address in header, clickable addresses (click→peer or copy)
- Bot: full WireMessage→TG Update mapping (encrypted base64, CallSignal,
  FileHeader, bot_message JSON)

Documentation:
- USAGE.md rewritten: complete user guide with all commands
- SERVER.md rewritten: full admin guide with all 50+ endpoints
- CLIENT.md rewritten: architecture, commands, keyboard, storage
- LLM_HELP.md created: 1083-word token-optimized reference for helper LLM

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 07:31:54 +04:00
Siavash Sameni
dbf5d136cf fix: WASM double-X3DH bug, federated aliases, deploy tooling
WASM fix (critical):
- encrypt_key_exchange_with_id was calling x3dh::initiate a second time,
  generating a new ephemeral key that didn't match the ratchet — receiver
  always failed to decrypt. Now stores X3DH result from initiate() and
  reuses it. Added 2 protocol tests confirming the fix + the bug.
- Bumped service worker cache to wz-v2 to force browsers to re-fetch.
- Disabled wasm-opt for Hetzner builds (libc compat issue).

Federation — alias support:
- resolve_alias falls back to federation peer if not found locally
- register_alias checks peer server before allowing — globally unique aliases
- Added resolve_remote_alias() and is_alias_taken_remote() to FederationHandle

Federation — key proxy fix:
- Remote bundles no longer cached locally (stale cache caused decrypt failures)
- Local vs remote determined by device: prefix in keys DB

Client fixes:
- Self-messaging blocked ("Cannot send messages to yourself")
- /peer <self> blocked
- last_dm_peer never set to self
- /r <message> sends reply inline (switches peer + sends in one command)

Deploy tooling:
- scripts/build-linux.sh with --ship (build + deploy + destroy)
- --update-all, --status, --logs commands
- WASM rebuilt on Hetzner VM before server binary
- deploy/ directory: systemd service, federation configs, setup script
- Journald log cap (50MB, 7-day retention)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 22:59:19 +04:00
Siavash Sameni
f8eaf30bb4 refactor: federation uses persistent WS instead of HTTP polling
- Server-to-server communication via WebSocket at /v1/federation/ws
- Auth as first WS frame (shared secret), presence + forwards over same connection
- Auto-reconnect every 3s on disconnect, instant presence push on connect
- Replaces HTTP REST polling (no more 5s intervals, lower latency)
- Removed dead HMAC helpers (auth is now direct secret comparison over WS)
- Simplified ARCHITECTURE.md mermaid diagrams for Gitea rendering

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:56:13 +04:00
Siavash Sameni
3e0889e5dc v0.0.21: TUI overhaul, WZP call infrastructure, security hardening, federation
TUI:
- Split 1,756-line app.rs monolith into 7 modules (types, draw, commands, input, file_transfer, network, mod)
- Message timestamps [HH:MM], scrolling (PageUp/Down/arrows), connection status dot, unread badge
- /help command, terminal bell on incoming DM, /devices + /kick commands
- 44 unit tests (types, input, draw with TestBackend)

Server — WZP Call Infrastructure (FC-2/3/5/6/7/10):
- Call state management (CallState, CallStatus, active_calls, calls + missed_calls sled trees)
- WS call signal awareness (Offer/Answer/Hangup update state, missed call on offline)
- Group call endpoint (POST /groups/:name/call with SHA-256 room ID, fan-out)
- Presence API (GET /presence/:fp, POST /presence/batch)
- Missed call flush on WS reconnect
- WZP relay config + CORS

Server — Security (FC-P1):
- Auth enforcement middleware (AuthFingerprint extractor on 13 write handlers)
- Session auto-recovery (delete corrupted ratchet, show [session reset])
- WS connection cap (5/fingerprint) + global concurrency limit (200)
- Device management (GET /devices, POST /devices/:id/kick, POST /devices/revoke-all)

Server — Federation:
- Two-server federation via JSON config (--federation flag)
- Periodic presence sync (every 5s, full-state, self-healing)
- Message forwarding via HTTP POST with SHA-256(secret||body) auth
- Graceful degradation (peer down = queue locally)
- deliver_or_queue() replaces push-or-queue in ws.rs + messages.rs

Client — Group Messaging:
- SenderKeyDistribution storage + GroupSenderKey decryption in TUI
- sender_keys sled tree in LocalDb

WASM:
- All 8 WireMessage variants handled (no more "unsupported")
- decrypt_group_message() + create_sender_key_from_distribution() exports
- CallSignal parsing with signal_type mapping

Docs:
- ARCHITECTURE.md rewritten with Mermaid diagrams
- README.md created
- TASK_PLAN.md with FC-P{phase}-T{task} naming
- PROGRESS.md updated to v0.0.21

WZP submodule updated to 6f4e8eb (IAX2 trunking, adaptive quality, metrics, all S-tasks done)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 16:45:58 +04:00
Siavash Sameni
4a4fa9fab4 v0.0.21: FC-CRATE-1 — make warzone-protocol importable standalone
Replaced workspace dep inheritance with explicit versions in
warzone-protocol/Cargo.toml. The crate now builds both as a
workspace member AND standalone.

WZP can now import warzone-protocol directly:
  warzone-protocol = { path = "../featherChat/warzone/crates/warzone-protocol" }

This means WZP can delete its mirrored identity/crypto code and use:
- warzone_protocol::identity::{Seed, IdentityKeyPair, PublicIdentity}
- warzone_protocol::crypto::{hkdf_derive, aead_encrypt, aead_decrypt}
- warzone_protocol::ethereum::{derive_eth_identity, EthAddress}
- warzone_protocol::message::{WireMessage, CallSignalType}
- warzone_protocol::types::Fingerprint

Single source of truth for identity derivation — no more HKDF mismatches.

28/28 tests pass. Zero warnings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 09:21:18 +04:00
Siavash Sameni
064a730b42 v0.0.21: WZP integration groundwork — CallSignal + token validation
WZP-FC-1: CallSignal WireMessage variant
- CallSignalType enum: Offer, Answer, IceCandidate, Hangup, Reject, Ringing, Busy
- Routed through existing E2E encrypted channels
- Server dedup handles new variant
- TUI shows "📞 Call signal: Offer" etc
- CLI recv prints call signals

WZP-FC-4: Token validation endpoint
- POST /v1/auth/validate { "token": "..." }
- Returns: { "valid": true, "fingerprint": "...", "alias": "..." }
- WZP relay calls this to verify featherChat bearer tokens
- Resolves alias alongside fingerprint

These two unblock WZP integration tasks WZP-S-2 (accept FC tokens)
and WZP-S-3 (signaling bridge mode).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 09:13:23 +04:00
Siavash Sameni
65f639052e Append WZP integration tasks to FUTURE_TASKS.md (238→676 lines)
featherChat side (10 tasks):
  WZP-FC-1: CallSignal WireMessage variant (2-4h)
  WZP-FC-2: Call state management + sled tree (1-2d)
  WZP-FC-3: WS handler for call signaling (0.5d)
  WZP-FC-4: Auth token validation endpoint (2-4h)
  WZP-FC-5: Group-to-room mapping (1d)
  WZP-FC-6: Presence/online status API (0.5-2d)
  WZP-FC-7: Missed call notifications (0.5d)
  WZP-FC-8: Cross-project identity verification test (2-4h) CRITICAL
  WZP-FC-9: HKDF salt investigation — VERIFIED: no mismatch (b""→None == None)
  WZP-FC-10: WZP web bridge shared auth (1-2d)

WZP side suggestions (9 items):
  WZP-S-1 through WZP-S-9 covering auth, signaling bridge,
  room access control, proto publishing, CLI flags, and
  6 hardcoded assumptions that conflict with integration.

All tasks reference specific file:line in both codebases.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 08:50:13 +04:00
Siavash Sameni
619af027dc Update warzone-phone submodule to ac3b997
WZP aligned HKDF info strings with featherChat:
- "warzone-ed25519-identity" → "warzone-ed25519"
- "warzone-x25519-identity" → "warzone-x25519"

Same seed now produces identical keys in both projects.
Shared identity prerequisite is met.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 08:27:49 +04:00
Siavash Sameni
007ca7521d FUTURE_TASKS.md: 18 optional tasks with questions-before-starting
High priority:
  1. Auth enforcement middleware
  2. Session auto-recovery
  3. Crypto audit plan

Medium priority:
  4. Extract web client from monolith
  5. Session state versioning
  6. Periodic auto-backup
  7. WireMessage versioning

Normal priority:
  8. Mule binary implementation
  9. libsignal migration assessment
  10. OIDC identity provider
  11. Smart contract ACL
  12. DNS federation
  13. WarzonePhone integration

Low priority:
  14. Message search
  15. Read receipts
  16. Typing indicators
  17. Message reactions
  18. Voice messages

Each task includes: what, why, effort estimate, and blocking
questions that must be answered before work begins.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 08:21:14 +04:00
Siavash Sameni
de1ce77fea IDP_SMART_CONTRACT.md: featherChat as IdP + on-chain ACL (1111 lines)
featherChat as Identity Provider:
- OIDC provider endpoints (/auth/oidc/authorize, /token, /userinfo)
- JWT tokens with fingerprint, alias, eth_address, groups claims
- Authentik integration (featherChat as upstream IdP, group sync)
- SAML support for enterprise

Smart Contract Access Control:
- FeatherChatACL Solidity contract (server/group/feature access)
- secp256k1 address from same BIP39 seed = on-chain identity
- NFT-gated access (ERC-721/ERC-1155 membership)
- Token-gated access (ERC-20 staking)
- DAO governance for group membership decisions
- UUPS upgradeable proxy pattern

Hybrid architecture:
- OIDC token carries on-chain permissions as claims
- Event-driven sync (WebSocket RPC + periodic poll + sled cache)
- L2 deployment (Arbitrum/Base/Polygon) for low gas costs

Feasibility: 7-11 weeks across 4 phases.
Comparison with SpruceID, Ceramic, Lens, XMTP.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 08:07:34 +04:00
Siavash Sameni
1c7b39c395 Rewrite WZP_INTEGRATION.md with confirmed code references (1209 lines)
All [SPECULATIVE] markers replaced with [CONFIRMED] from actual WZP code.

Key discoveries:
- HKDF info string mismatch: featherChat uses "warzone-ed25519",
  WZP uses "warzone-ed25519-identity" — same seed, different keys.
  Requires 2-line fix in wzp-crypto/src/handshake.rs before integration.
- Media is NOT DTLS-SRTP: WZP uses ephemeral X25519 DH + ChaCha20-Poly1305
  with deterministic nonces (WireGuard-like, not WebRTC-like)
- Transport is QUIC (quinn), not WebRTC/ICE
- FEC is RaptorQ fountain codes, not Opus inband
- 5 codecs: Opus 24k → Codec2 1200bps with adaptive switching
- Relay operates on encrypted packets (zero-knowledge relay)

18 sections with concrete API contracts, code file:line references,
and phased implementation roadmap.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 08:02:30 +04:00
Siavash Sameni
95e7e0b1a9 Add WarzonePhone as git submodule at warzone-phone/
ssh://git@git.manko.yoga:222/manawenuz/wz-phone.git

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 07:54:14 +04:00
Siavash Sameni
f7a517d8ea WZP_INTEGRATION.md: featherChat ↔ WarzonePhone integration spec (1001 lines)
Covers: shared identity model (same BIP39 seed), authentication flow
(Ed25519 signed tokens), call signaling via WireMessage::CallSignal,
DTLS-SRTP media encryption bootstrapped from Double Ratchet,
group calls (SFU + Sender Keys), warzone scenarios (voice messages
as attachments, mule delivery for missed calls).

Phased roadmap: shared identity → signaling → encrypted calls → group calls.

featherChat-side details confirmed against code.
WZP-side details marked [SPECULATIVE] (WZP codebase was inaccessible).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 05:38:45 +04:00