| .. | .. |
|---|
| 6 | 6 | ## CRITICAL (Must fix before submission) |
|---|
| 7 | 7 | |
|---|
| 8 | 8 | - [x] **C1: Remove NSAllowsArbitraryLoads** — ATS bypass, Apple will reject. Use NSAllowsLocalNetworking only *(fixed 2026-03-25)* |
|---|
| 9 | | -- [ ] **C2: Add TLS to MQTT** — All conversations and auth token travel in plaintext. Set `client.secure = true`, configure TLS on AIBroker broker |
|---|
| 10 | | -- [ ] **C3: Remove debug log files in production** — `mqtt_debug.log` and `_chatLog` write truncated message content to Documents. Wrap in `kDebugMode` or remove entirely |
|---|
| 9 | +- [x] **C2: Add TLS to MQTT** — All conversations and auth token travel in plaintext. Set `client.secure = true`, configure TLS on AIBroker broker *(fixed 2026-03-25 — self-signed cert auto-generated at ~/.aibroker/tls/, onBadCertificate accepts it; TODO: pin cert fingerprint)* |
|---|
| 10 | +- [x] **C3: Remove debug log files in production** — `mqtt_debug.log` and `_chatLog` write truncated message content to Documents. Wrap in `kDebugMode` or remove entirely *(fixed 2026-03-25)* |
|---|
| 11 | 11 | |
|---|
| 12 | 12 | ## HIGH (Should fix before submission) |
|---|
| 13 | 13 | |
|---|
| 14 | | -- [ ] **H1: Unbounded image cache** — `_imageCache` in message_bubble.dart grows without limit. Add LRU eviction (cap at 50) |
|---|
| 15 | | -- [ ] **H2: Audio temp files never cleaned** — `_base64ToFile` creates .m4a files never deleted. Clean up after playback completes |
|---|
| 16 | | -- [ ] **H3: TextEditingController leak** — Rename dialog in session_drawer.dart creates controller but never disposes it |
|---|
| 17 | | -- [ ] **H4: Input validation on settings** — No validation on host IPs, port range, MAC format. Add regex validators |
|---|
| 18 | | -- [ ] **H5: LifecycleObserver never removed** — AudioService.init() adds observer but dispose() doesn't remove it |
|---|
| 14 | +- [x] **H1: Unbounded image cache** — `_imageCache` in message_bubble.dart grows without limit. Add LRU eviction (cap at 50) *(fixed 2026-03-25)* |
|---|
| 15 | +- [x] **H2: Audio temp files never cleaned** — `_base64ToFile` creates .m4a files never deleted. Clean up after playback completes *(fixed 2026-03-25)* |
|---|
| 16 | +- [x] **H3: TextEditingController leak** — Rename dialog in session_drawer.dart creates controller but never disposes it *(fixed 2026-03-25)* |
|---|
| 17 | +- [x] **H4: Input validation on settings** — No validation on host IPs, port range, MAC format. Add regex validators *(fixed 2026-03-25)* |
|---|
| 18 | +- [x] **H5: LifecycleObserver never removed** — AudioService.init() adds observer but dispose() doesn't remove it *(fixed 2026-03-25)* |
|---|
| 19 | 19 | - [ ] **H6: MQTT token in memory** — Acceptable for personal use, document as known limitation |
|---|
| 20 | 20 | |
|---|
| 21 | 21 | ## MEDIUM (Improve before submission) |
|---|
| .. | .. |
|---|
| 51 | 51 | | UIBackgroundModes: audio | PASS | - | |
|---|
| 52 | 52 | | Privacy Policy | FAIL | Fix L2 | |
|---|
| 53 | 53 | | PrivacyInfo.xcprivacy | FAIL | Fix L1 | |
|---|
| 54 | | -| TLS for network | FAIL | Fix C2 | |
|---|
| 54 | +| TLS for network | PASS | Fixed C2 - self-signed cert, onBadCertificate=true | |
|---|