| 1 | # Memoria UX review · 12 September 2026 |
| 2 | |
| 3 | ## MemoriaWorkspace.swift |
| 4 | |
| 5 | 1. **Medium: give desktop results enough reading width.** The original narrow |
| 6 | sidebar wrapped snippets excessively. Split-view width hints alone were |
| 7 | ignored in the actual Mac render; a Mac-only minimum frame now enforces |
| 8 | 280 points, with a 340-point ideal. The compact Answer action fits clearly. |
| 9 | |
| 10 | Before: column min 220 / ideal 260. |
| 11 | After: column min 280 / ideal 340, plus `.frame(minWidth: 280, idealWidth: 340)` |
| 12 | on Mac. iPhone keeps the native compact navigation layout. |
| 13 | |
| 14 | 2. **Medium: remove internal indexing details.** Passage 0 and similar ordinals |
| 15 | offered no useful navigation. Results now show a named source type, readable |
| 16 | snippet and source number. An explicit results section separates matches |
| 17 | from the Answer action. Result accessibility combines the row's description. |
| 18 | |
| 19 | Before: `Source [1] · Passage 0` |
| 20 | After: `Source 1`, with source type and snippet above. |
| 21 | |
| 22 | 3. **Medium: anchor answers to the current search.** The generic slogan is |
| 23 | replaced by the query and a clear answer purpose. Before searching, a native |
| 24 | ContentUnavailableView explains how to start. A stable thinking indicator |
| 25 | stays visible while permission rechecks temporarily clear results. Sources |
| 26 | have a divider, document labels and 44-point minimum tap areas. |
| 27 | |
| 28 | 4. **Medium: prove source navigation in compact and split layouts.** The |
| 29 | selected passage text has a detail-only `sourcePassage` identifier. Tests |
| 30 | assert its existence and exact body rather than matching the sidebar snippet. |
| 31 | Only compact navigation expects a Source navigation bar. The final test |
| 32 | scopes its tap to the sidebar result cell: on iPad the same title also |
| 33 | appears as the search-query heading, so a global text selector was ambiguous. |
| 34 | |
| 35 | ## AddNoteView.swift |
| 36 | |
| 37 | **Medium: label the editable note body for assistive technology.** |
| 38 | |
| 39 | Before: `TextEditor(text: $bodyText)` |
| 40 | After: `TextEditor(text: $bodyText).accessibilityLabel("Note")` |
| 41 | |
| 42 | Priority addressed: result readability and navigation, then contextual answers, |
| 43 | progress feedback and editor accessibility. |
| 44 | |
| 45 | ## Method and validation |
| 46 | |
| 47 | Applied `swiftui-pro` design, accessibility and navigation references, plus |
| 48 | `swiftui-native-component-design` semantics/control/accessibility guidance. |
| 49 | Reviewed actual SwiftUI renders on Mac, iPhone and iPad; checked light mode and |
| 50 | accessibility-large Dynamic Type in dark mode on iPhone. Real forms/navigation |
| 51 | are exercised through the isolated authenticated Go fixture and XCTest. |
| 52 | No backend, auth, model retrieval or permission behavior changed. |
| 53 | |
| 54 | Independent reviewer: `/root/canary_release_review`, dispatched as `gpt-6-astra` |
| 55 | with high reasoning; runtime identity not independently verified. Screenshots |
| 56 | and source corrections were reviewed independently. Full VoiceOver walkthrough, |
| 57 | localization and every accessibility size remain hands-on acceptance work. |
| 58 | |
| 59 | Final independent review approved. The scoped iPad test passed (15.496 seconds |
| 60 | XCTest; 38.230 seconds complete fixture). The reviewer removed only the result |
| 61 | cell tap: detail-only sourcePassage assertions failed as intended. The test was |
| 62 | restored byte-for-byte to the passing version, then this mutation comment was |
| 63 | added. The mutation's XCTest suite finished with the intended failures, but its |
| 64 | xcodebuild watcher hung during teardown and was terminated; that watcher is not |
| 65 | claimed as a completed normal test run. Evidence: `/tmp/memoria-ux-scoped-clean.log` |
| 66 | and `/tmp/memoria-ux-scoped-mutation.log`. |
| 67 | |