Why: the module was written but never compiled, so nothing about it was
proved. Building it found a name clash and a theme that would have crashed
every device below Android 10.
What:
- KeepOrgProvider.requireContext -> ctx(): ContentProvider gained
requireContext() in API 30, and Kotlin refused the silent hiding.
- The application theme was @android:style/Theme.DeviceDefault.DayNight,
which is API 29 while minSdk is 26. Replaced with @style/AppTheme, plain
DeviceDefault in values/ and DayNight in values-v29/.
- Backup exclusions: data_extraction_rules.xml and backup_rules.xml exclude
every domain for both cloud backup and device transfer. The session token
authenticates as the user and the mirrored files are the organization's
password databases; neither belongs in a backup.
- User-facing strings moved from code into strings.xml, so the app is
translatable. Layouts stay in code, as before.
- mipmap-anydpi-v26 -> mipmap-anydpi (the qualifier is redundant at minSdk
26), and the redundant activity label is gone.
- Lint is configured to write a text report, and `make android-lint` runs it;
`make android` now fails with a clear message when ANDROID_HOME has no SDK.
Proved: the unsigned release APK builds (656 KB), lint reports "No issues
found", and the packaged DEX contains all 16 classes including every manifest
component. Toolchain used: JDK 21, Gradle 8.10.2, SDK platform 35 and
build-tools 35.0.0; on this arm64 host Google's x86-64 aapt2 runs under
qemu-user-static with amd64 multiarch libraries, which android/README.md now
documents. The app has still not run on a device: there is none here.
Why: the set has to be installable and publishable, not just buildable, and
the next person needs the reasoning, not only the code.
What:
- android/: Kotlin client with no third-party dependencies. A
DocumentsProvider publishes the mirrored databases to every file picker, so
KeePassDX opens them as ordinary documents; closing a file it wrote
triggers a sync. A foreground service holds the event stream open.
Mirror.decide transcribes the Go merge table, so both platforms resolve a
conflict identically.
- Makefile as the single entrypoint, with file targets so only what changed
is rebuilt: host and cross builds, both .deb packages, the macOS DMG with
its /Applications symlink, the Windows zip, the APK under its F-Droid
publishing name, and manual-only android-publish.
- versions.mk holds one version per platform plus the Android versionCode;
`make bump` and `make changelog` move them. Debian changelog is tracked.
- systemd units (hardened system unit for the server, user unit for the
agent), macOS bundle and launch agent, Windows Task Scheduler job.
- docs/HANDOVER.md on architecture and every decision that shaped it,
docs/PROTOCOL.md for the API, README for the quick start.
Proved: make check and make test-race both pass; built both .deb packages and
inspected their contents, built the Windows zip, cross-compiled all five
desktop targets, and exercised make bump. The Android module is written but
not compiled: no JDK or Android SDK in this environment, which HANDOVER.md
states plainly.