Update CLAUDE.md with security + performance audit results

This commit is contained in:
Bruno Deanoz 2026-06-24 09:40:26 +02:00
parent 3b73e15376
commit 89fe5fd2ae

View file

@ -57,7 +57,7 @@ ui/
### Key components
- **KaizenApi** (`net/KaizenApi.kt`) — singleton `object`, all HTTP calls via OkHttp. Streaming chat returns `Flow<String>` with incremental sentinel-stripping.
- **KaizenApi** (`net/KaizenApi.kt`) — singleton `object`, all HTTP calls via OkHttp. Three clients sharing one connection pool: `baseClient` (30s timeout, also used by LiveClient), `streamClient` (infinite timeout, chat only), `imageClient` (same as baseClient). Streaming chat returns `Flow<StreamState>` via `streamClient`. `uploadStream()` accepts InputStream for zero-copy file uploads.
- **StreamConsumer** (`net/StreamConsumer.kt`) — O(chunk-size) incremental parser, each character visited exactly once across the entire stream.
- **SessionViewModel** (`net/SessionViewModel.kt`) — Compose snapshot state for auth session. Holds `ServerConfig` (baseUrl, token, model, email, speed). Persisted in `EncryptedSharedPreferences` via `SecureStore`.
- **ChatViewModel** (`chat/ChatViewModel.kt`) — owns Room database instance + repositories. Created in `MainActivity`, passed to `ChatScreen`.
@ -293,6 +293,7 @@ All committed on `main`. Compile-verified on Mac (`./gradlew :app:compileDebugKo
| `1c9491e` | **Markdown spacing** — heading spacing 18→24/20dp, list items 8dp gap + muted bullets, blockquote 12dp inset |
| `430d5b6` | **Flat sidebar user row** — removed heavy card (background, border, shadow), replaced with flat row + thin separator |
| — | **Branch navigation (tree support)**`ChatTree` data structure mirrors web frontend's tree. Edit creates a branch (sibling node with same parentId) instead of deleting messages. Regenerate creates a new assistant branch. `BranchNavigator` UI (chevron arrows + "1/3" counter) on messages with siblings. `activeRootId`/`activeChild` synced to server via PATCH. `StoredMessage.parentId` parsed from API. `patchConversation` handles JSON object values for `activeChild` |
| `3b73e15` | **Security hardening + performance pass** — JSON injection fix (deleteMessage), separate stream OkHttpClient (30s timeout on normal requests), disable backup, block cleartext, strip URLs from logs. Shared connection pool (LiveClient reuses KaizenApi.baseClient), eliminate duplicate fetchMe, parallel prefetchMissing, streaming file uploads (no readBytes), O(1) message index during streaming, send() race condition fix, voice recording file read on IO thread |
**Earlier UI/feel work (Phase 0 prototype → feel-first):**
- Liquid glass styling, floating panels, glassmorphic sidebar
@ -407,7 +408,13 @@ All done:
- [x] **Security settings** — biometric toggle, signed-in devices with remote revoke, password change
- [x] **Password change**`POST /api/v1/auth/change-password` (Argon2id, rate-limited)
- [x] **Device management**`GET/DELETE /api/v1/auth/tokens` (list + revoke, can't revoke self)
- [x] **JSON injection fix**`deleteMessage` was using raw string interpolation for JSON body, now uses `kotlinx.serialization`
- [x] **Separate stream client** — main `OkHttpClient` has 30s `readTimeout` (was infinite for ALL requests). Streaming-only `streamClient` keeps `readTimeout(0)`. Prevents normal API calls from hanging forever
- [x] **Disable backup**`android:allowBackup="false"`. EncryptedSharedPreferences without KeyStore on restore → crash
- [x] **Block cleartext traffic**`android:usesCleartextTraffic="false"` explicit in manifest
- [x] **Strip server URLs from logs**`Log.w` calls no longer include `$baseUrl`, prevents leaking instance URLs in release logcat
- [ ] **`FLAG_SECURE`** on sensitive screens — see `LATER.md` §1B
- [ ] **Certificate pinning** for default server (`ask.kryptomrx.de`)
### 4. Features for parity with the web