10 june 2026
wednesdayToday was mostly about turning my “mobile companion” into something that works standalone: offline-first, on-device search, and a clearer unpaired UX. I also invested in tooling (Claude Code + Android toolchain) and hit a few real-world “native mobile is different” issues that were good forcing functions.
What I learned
- Sandboxed environments can break Git in surprising ways. A persistent
.git/index.lock(and filesystem mount behavior) blocked commits; the practical fix was to clean lock files and do write operations in a real local shell. - Expo prebuild can clobber tracked TypeScript config. Running prebuild/Android builds deleted
expo-env.d.tsand alteredtsconfig.json, causing typecheck failures until I restored the committed versions. - Android build hygiene matters. I ran into a Gradle/JDK mismatch (JDK 21 vs required JDK 17) and fixed it by explicitly pointing
JAVA_HOMEat a JDK 17 install. - Emulator ≠ real device for on-device ML. OCR inference triggered a native crash (SIGILL) in the emulator even after model download/caching. The takeaway: some ExecuTorch inference paths aren’t reliable on my Apple Silicon emulator; hardware verification is required.
- On-device “Q&A” doesn’t always require a big model. Splitting retrieval (local DB/vector search) from generation (LLM wording) makes offline mode feasible: many queries can be answered with local lookups/snippets.
What I built
- Set up Claude Code CLI (install + OAuth) and used it to inspect repos, run status checks, and coordinate doc/code changes.
- Android dev environment: installed/configured Android Studio, SDKs, created an emulator, booted it, and successfully built/installed the app via the Expo/Gradle pipeline.
- Project doc sync across desktop + mobile repos: updated README/ROADMAP/HANDOFF/IMPROVEMENTS to match actual repo state and clarified workflow rules where they were contradictory.
- Mobile Phase 0 shipped (offline-first core):
- Added SQLite-backed local store (
expo-sqlite) with a dev self-test run at app launch. - Integrated on-device embeddings using
react-native-executorchand validated via logcat self-tests. - Implemented offline semantic search (ranking + UI) and added a dedicated Memories screen reachable even when unpaired.
- Phase 1 capture work started:
- Wired an image-pick / OCR plumbing path (plus test-safe module structure to avoid native imports in Jest).
- Prototyped voice capture pipeline using Expo audio streaming, with waveform helpers and a Record/Stop flow (including a silence guard for emulator quirks).
- UX/routing improvements: changed routing so unpaired users land in an on-device-first experience instead of hitting a pairing wall; validated Connect/Skip round-trips in the emulator.
- Icon/branding cleanup:
- Generated and verified updated Android launcher/adaptive icons, fixed an APK signature mismatch by uninstalling/reinstalling.
- Began aligning desktop icon/favicons so required assets are actually tracked (fixing
.gitignoreissues that would break fresh builds).
Experimenting with
- Feature parity planning for desktop vs mobile: produced and iterated on parity docs and a phased roadmap, then revised it toward a more realistic “on-device core + optional desktop sync” model.
- On-device OCR / STT / LLM feasibility with ExecuTorch hooks and model/download behavior, including the practical limits of emulator-based validation.