Create the native Android project structure that will host the Kotlin application without weakening IronStorage's Rust-owned domain boundary.
Scope
Add an android/ Gradle build using Gradle Kotlin DSL, a version catalog, the Android application plugin, Kotlin, Compose, Hilt/KSP, and reproducible wrapper/toolchain settings.
Use a single-activity Compose application and separate modules where the boundary is useful: application/navigation, feature UI modules, Android platform adapters, and the generated Rust bridge. Avoid a module-per-screen architecture.
Give the production application the stable package/application ID de.rfc1437.ironstorage; derive service/test IDs without changing the main identity.
Define build types, signing placeholders, manifest merging, resources, localization structure, ProGuard/R8 rules, native debug symbols, and deterministic version metadata without committing signing secrets.
Enforce allowed dependency direction: Compose features depend on an Android-facing repository/facade; only that facade depends on generated UniFFI types; platform adapters implement narrow OS contracts; no feature module reads the password-store filesystem.
Pin stable dependencies through the version catalog and enable dependency verification/locking where supported.
Add debug fixtures/fakes for every shell state so UI development does not require real secret material.
Libraries and tools
Android Gradle Plugin, Kotlin Gradle plugin, Compose BOM/Material 3, Activity Compose, Lifecycle, Navigation, Hilt with KSP, Gradle version catalogs, Android Lint, and the NDK plugin/toolchain settings required by the Rust packaging issue.
Acceptance criteria
A clean checkout can configure and assemble a placeholder debug APK with no externally installed helper process at application runtime.
Package IDs, min/target SDK policy, namespace, modules, dependency direction, and build types match #88.
Release configuration contains no development endpoint, credential, key, or signing material.
Android feature modules cannot directly depend on Rust implementation crates, filesystem/Git libraries, or competing crypto/OTP libraries.
Gradle configuration is cacheable and CI-ready, and generated/native outputs stay out of source control unless explicitly reviewed as release artifacts.
User-directed scope: Android release and CI targets are arm64-v8a and armeabi-v7a. x86_64 Android is excluded for now. Validation for every Android milestone issue uses emulator devices only; physical-device testing and physical-device checklists are excluded. Record the limits of available ARM emulator/API images without claiming physical-device coverage.
## Goal
Create the native Android project structure that will host the Kotlin application without weakening IronStorage's Rust-owned domain boundary.
## Scope
- Add an `android/` Gradle build using Gradle Kotlin DSL, a version catalog, the Android application plugin, Kotlin, Compose, Hilt/KSP, and reproducible wrapper/toolchain settings.
- Use a single-activity Compose application and separate modules where the boundary is useful: application/navigation, feature UI modules, Android platform adapters, and the generated Rust bridge. Avoid a module-per-screen architecture.
- Give the production application the stable package/application ID `de.rfc1437.ironstorage`; derive service/test IDs without changing the main identity.
- Define build types, signing placeholders, manifest merging, resources, localization structure, ProGuard/R8 rules, native debug symbols, and deterministic version metadata without committing signing secrets.
- Enforce allowed dependency direction: Compose features depend on an Android-facing repository/facade; only that facade depends on generated UniFFI types; platform adapters implement narrow OS contracts; no feature module reads the password-store filesystem.
- Pin stable dependencies through the version catalog and enable dependency verification/locking where supported.
- Add debug fixtures/fakes for every shell state so UI development does not require real secret material.
## Libraries and tools
Android Gradle Plugin, Kotlin Gradle plugin, Compose BOM/Material 3, Activity Compose, Lifecycle, Navigation, Hilt with KSP, Gradle version catalogs, Android Lint, and the NDK plugin/toolchain settings required by the Rust packaging issue.
## Acceptance criteria
- A clean checkout can configure and assemble a placeholder debug APK with no externally installed helper process at application runtime.
- Package IDs, min/target SDK policy, namespace, modules, dependency direction, and build types match #88.
- Release configuration contains no development endpoint, credential, key, or signing material.
- Android feature modules cannot directly depend on Rust implementation crates, filesystem/Git libraries, or competing crypto/OTP libraries.
- Gradle configuration is cacheable and CI-ready, and generated/native outputs stay out of source control unless explicitly reviewed as release artifacts.
Depends on #88. Part of #87.
## Android support update (2026-10-08)
User-directed scope: Android release and CI targets are **arm64-v8a** and **armeabi-v7a**. x86_64 Android is excluded for now. Validation for every Android milestone issue uses emulator devices only; physical-device testing and physical-device checklists are excluded. Record the limits of available ARM emulator/API images without claiming physical-device coverage.
hugo
added this to the 06 - Implement an Android version of the software milestone 2026-08-17 19:10:17 +00:00
Added the native single-activity Compose project with app, features, core, platform and rust-bridge modules; stable de.rfc1437.ironstorage identity; SDK 26/37 policy; deterministic versions; unsigned/minified release configuration; backup exclusions; and the existing iPhone vault artwork adapted for Android adaptive/themed launchers. The Kotlin facade and Hilt ViewModel expose typed immutable StateFlow presentation state. Gradle enforces module edges and competing-domain dependency restrictions; the Rust android-build tool checks source boundaries and generates all five debug shell states directly from storage-owned MobileShell fixtures. Runtime/native domain wiring remains assigned to #91/#92, and complete adaptive navigation to #102.
Pinned stable Gradle/AGP/Kotlin/KSP/Hilt/AndroidX versions, verified wrapper checksums, committed dependency SHA-256 verification metadata and configuration locks, and disabled automatic JDK substitution. Generated/local/signing/build outputs are ignored. Build/update procedures and boundary review limitations are documented in android/README.md. Instrumented tests retain installed APKs so the persistent emulator's app data is preserved.
Validation and review against every acceptance criterion:
All required Rust gates passed: fmt, warning-denied workspace check, clippy, and 411 workspace tests.
ktlintCheck, debug/release assembly, debug unit tests and Android Lint passed with strict artifact verification/locks.
A fresh source export with no project-generated outputs or local.properties assembled the debug APK using documented installed toolchains and shared dependency caches; configuration-cache reuse passed.
API 37 Medium Phone instrumented UI validation tapped every fixture and each of the five tabs (25 combinations), checking the Rust-provided headings. Additional autonomous ADB UI inspection/taps/swipes verified Loading, Empty, Ready, Locked, Error and Preferences; screenshots verified system-bar spacing and the vault launcher icon.
An app-private validation file survived install -r and another instrumented run; the app stayed installed. No AVD/data/keychain reset was used.
Release APK identity/SDK metadata and absence of debug fixture classes were checked. No signing key, credential or development endpoint is configured.
The reviewed result completes #89's scaffold scope; subsequent milestone issues implement real repository/security workflows.
Implemented in commit e079b82 (pushed to main).
Added the native single-activity Compose project with app, features, core, platform and rust-bridge modules; stable de.rfc1437.ironstorage identity; SDK 26/37 policy; deterministic versions; unsigned/minified release configuration; backup exclusions; and the existing iPhone vault artwork adapted for Android adaptive/themed launchers. The Kotlin facade and Hilt ViewModel expose typed immutable StateFlow presentation state. Gradle enforces module edges and competing-domain dependency restrictions; the Rust android-build tool checks source boundaries and generates all five debug shell states directly from storage-owned MobileShell fixtures. Runtime/native domain wiring remains assigned to #91/#92, and complete adaptive navigation to #102.
Pinned stable Gradle/AGP/Kotlin/KSP/Hilt/AndroidX versions, verified wrapper checksums, committed dependency SHA-256 verification metadata and configuration locks, and disabled automatic JDK substitution. Generated/local/signing/build outputs are ignored. Build/update procedures and boundary review limitations are documented in android/README.md. Instrumented tests retain installed APKs so the persistent emulator's app data is preserved.
Validation and review against every acceptance criterion:
- All required Rust gates passed: fmt, warning-denied workspace check, clippy, and 411 workspace tests.
- ktlintCheck, debug/release assembly, debug unit tests and Android Lint passed with strict artifact verification/locks.
- A fresh source export with no project-generated outputs or local.properties assembled the debug APK using documented installed toolchains and shared dependency caches; configuration-cache reuse passed.
- API 37 Medium Phone instrumented UI validation tapped every fixture and each of the five tabs (25 combinations), checking the Rust-provided headings. Additional autonomous ADB UI inspection/taps/swipes verified Loading, Empty, Ready, Locked, Error and Preferences; screenshots verified system-bar spacing and the vault launcher icon.
- An app-private validation file survived install -r and another instrumented run; the app stayed installed. No AVD/data/keychain reset was used.
- Release APK identity/SDK metadata and absence of debug fixture classes were checked. No signing key, credential or development endpoint is configured.
The reviewed result completes #89's scaffold scope; subsequent milestone issues implement real repository/security workflows.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Goal
Create the native Android project structure that will host the Kotlin application without weakening IronStorage's Rust-owned domain boundary.
Scope
android/Gradle build using Gradle Kotlin DSL, a version catalog, the Android application plugin, Kotlin, Compose, Hilt/KSP, and reproducible wrapper/toolchain settings.de.rfc1437.ironstorage; derive service/test IDs without changing the main identity.Libraries and tools
Android Gradle Plugin, Kotlin Gradle plugin, Compose BOM/Material 3, Activity Compose, Lifecycle, Navigation, Hilt with KSP, Gradle version catalogs, Android Lint, and the NDK plugin/toolchain settings required by the Rust packaging issue.
Acceptance criteria
Depends on #88. Part of #87.
Android support update (2026-10-08)
User-directed scope: Android release and CI targets are arm64-v8a and armeabi-v7a. x86_64 Android is excluded for now. Validation for every Android milestone issue uses emulator devices only; physical-device testing and physical-device checklists are excluded. Record the limits of available ARM emulator/API images without claiming physical-device coverage.
Implemented in commit
e079b82(pushed to main).Added the native single-activity Compose project with app, features, core, platform and rust-bridge modules; stable de.rfc1437.ironstorage identity; SDK 26/37 policy; deterministic versions; unsigned/minified release configuration; backup exclusions; and the existing iPhone vault artwork adapted for Android adaptive/themed launchers. The Kotlin facade and Hilt ViewModel expose typed immutable StateFlow presentation state. Gradle enforces module edges and competing-domain dependency restrictions; the Rust android-build tool checks source boundaries and generates all five debug shell states directly from storage-owned MobileShell fixtures. Runtime/native domain wiring remains assigned to #91/#92, and complete adaptive navigation to #102.
Pinned stable Gradle/AGP/Kotlin/KSP/Hilt/AndroidX versions, verified wrapper checksums, committed dependency SHA-256 verification metadata and configuration locks, and disabled automatic JDK substitution. Generated/local/signing/build outputs are ignored. Build/update procedures and boundary review limitations are documented in android/README.md. Instrumented tests retain installed APKs so the persistent emulator's app data is preserved.
Validation and review against every acceptance criterion:
The reviewed result completes #89's scaffold scope; subsequent milestone issues implement real repository/security workflows.