Clover, 2026-10-11: "something i think i want us to work on next is android port. what would block android?"
Read-only readiness at pushed main 33aa2ae1: shared format/editor/replica/SMB/rendering are reusable. No Android host/JNI/build/release lane exists, and the mobile surface constructor is CAMetalLayer-specific. Android SDK is installed; NDK, emulator system image/AVD, Android Rust target, and a configured JDK are missing. Host work includes Surface lifecycle, keyboard composition/selection, clipboard, accessibility, cache recovery and credential storage. Existing notebook APIs require paths and append/header commits; Android document providers expose URIs with provider-specific capabilities, so shared/cloud folders need an adapter and concurrency proof.
Proposed first milestone: ARM64 emulator APK using a disposable app-private notebook; shared canvas, keyboard editing, force-stop and offline reopening preserve edits. Then verify embedded SMB and document-provider storage separately. Minimum Android version, phone/tablet scope and distribution remain owner decisions. No port implementation has started.
Assisted-by: gpt-6
Android groundwork is on main: explicit NDK/API tooling and ANativeWindow create/detach/reattach preserve the same editor. Commit 96eb01ef499b. Actual ARM64 API24 Rust build and C-header consumer link pass with 16KB ELF alignment; native mobile tests (44 pass, one existing ignore), Clippy on native/iOS/Android, Xcode build and the exact changed-source CI pass. A fresh iOS simulator also retained the same cached notebook and offline edit across cold reopen, then published after restoration. This is the native surface foundation; no Android APK, JNI host, provider-URI backend or Android device runtime is shipped. Multi-file coordination remains separate in #120.
Assisted-by: gpt-6.1-sol
Provider capability lab is on main (849fdb2d), separate from the Android app. Actual API36 tests with different provider/client UIDs verified Activity-result read/RW grants, opaque document identities, changed rename URIs, non-seekable descriptors, provider errors, offline recovery and persisted grants after process restart. The restarted client retained exact edited bytes; both test APKs and owned emulator/ADB were removed. Controlled delayed visibility confirms that local fsync/close does not establish another client’s view. Exact-source tooling gate and four bounded teardown-failure cases passed. This is a synthetic DocumentsProvider fixture, not a commercial-provider durability or locking guarantee. The port remains open; multi-file coordination stays in #120. QA evidence remains private.
Assisted-by: gpt-6.1-sol
Source audit of unpublished Reader candidate 76298065: the private Android host calls no Reader/reload APIs, and all 31 public C signatures it uses remain unchanged. Reader projection starts OFF. The private lab remains pinned to its original 6eb source; importing its adapter onto 762 would fail at the old Accessibility.update arguments and removed View.reading field. That adapter needs an explicit migration and fresh Android compilation, then its own IME/accessibility/surface/cold-written tests. iOS Reader results do not establish Android behavior or #136 custody; provider write-back remains separate. Evidence stays private. No Android migration or runtime result is claimed.
Assisted-by: gpt-6.1-sol
The private Android cold-reopen check currently runs before provider access is made unavailable, and its final assertion requires the provider to remain readable. It therefore does not cover Clover’s “contents disappear after reopening while offline” report. The actual host reuses the registered private notebook/cache; a missing provider must not hide that copy. Add a distinct cold-reopen regression with provider reads failing throughout, preserving the original registration and SQLite replica, exact notebook/page identities, ordered edits and written barriers. This is a test-coverage finding, not evidence of Android data loss. Reader Mode remains off; provider write-back and edit custody remain separate in #120 and #136. Evidence stays private.
Assisted-by: gpt-6.1-sol
The first Android app is on main (d8a3bb04). apps/android is a Java + C host built without Gradle into an ARM64 APK for Android 8.0 and up. On an API 36 emulator it creates a notebook in app storage, draws the page, and keeps the same editor across rotation and Home. Typing works with the on-screen keyboard and adb input: composing, Backspace, Enter and the arrow keys. Section replicas are now moved into place with a no-replace rename, because Android forbids apps from making hard links. The Rust half builds in release, because the emulator's Vulkan driver crashes on wgpu's debug object names.
Next: keeping edits across a force-stop and an offline cold start, then a CI lane. Still unverified: Android 8–10 may block the raw renameat2 call replicas now use. Min version, form factor and distribution are still Clover's call; work proceeds on API 26, phone first, sideloaded APK.
Assisted-by: claude-opus-5.5
Android now opens notebooks through document providers (main c345a48e). The overflow menu has "Open Notebook Folder…" and "Open Section File…". The pick is remembered with its persisted grant, and the status line shows Offline / Read Only / Not Saving / Access Lost.
On an API 36 emulator, with both the built-in Documents provider and a lab provider:
Finishing the app now keeps the offline copies; only closing the notebook deletes them. That was the likely cause of the earlier "contents disappear after reopening while offline" report.
Providers that can only replace a whole file publish too. An upload another device overwrote, or one cut off partway, comes back through the conflict-version merge. Only this device's own cut-off upload is ever rewritten.
Still open: SMB, Live Share, Reader Mode and stylus on Android; release signing and distribution; a test on Android 8–10 if min API stays 26.
Assisted-by: claude-opus-5.5
Needs Clover before the first APK ships: the release signing key (it's permanent, since installs can only update from the same key) and how the APK is distributed (lean: a sideloaded APK in the release folder, Play later). Min API 26 is decided. Android 8 and 10 now run on the emulators; #153 is the one leftover there.
Assisted-by: claude-opus-5.5