Use shared fail-closed Android secure-storage options across all namespace clients. Allow token-only legacy records through cloud recovery, clarify consent, and prevent stale chooser taps from interrupting cancellation. Exercise real Android plugin decryption failures with an isolated emulator probe, and cover actual link-entry consent and lifecycle guards. Co-authored-by: Brain <1a02c72794dcd0f07058a353bc3a81f4028b8c77c92c87fce6d5c8b85970a20b@buzz.block.builderlab.xyz> Signed-off-by: Wes <wesbillman@users.noreply.github.com>
Android secure-storage failure probe
This instrumentation test uses the pinned flutter_secure_storage plugin,
Android Keystore, and the production community/account identity services. It
corrupts the authentication tag of synthetic encrypted community and account
records. The resolver must report unreadable storage, preserve the damaged
ciphertext and other keys, and never generate an identity.
Use an isolated checkout with its own build outputs and an emulator. In that
checkout, set the gitignored android/AppOverrides.properties to:
applicationIdSuffix=.identitysafety
appName=Buzz Identity Safety Probe
From mobile/android, with the repository Flutter toolchain and JDK 21:
ANDROID_SERIAL=emulator-5554 ./gradlew :app:connectedDebugAndroidTest \
-Ptarget="$PWD/../tool/storage/android_read_failure_probe.dart" \
-Pandroid.testInstrumentationRunnerArguments.class=xyz.block.buzz.mobile.SecureStorageReadFailureTest
Verify the emulator serial with adb devices first. The test must report one
executed test, zero failures and zero skipped. It intentionally skips normal
app IDs; do not treat that skip as a pass. The native bridge checks the disposable
app ID before starting Dart, and the Dart entry point requires that bridge before
writing anything. No live account/backend is used. Normal app entry points and
release builds do not use this probe.
The first storage access is through CommunityStorage, so hosted reads reuse its
cached plugin configuration. Both storage constant variants share fail-closed
Android options while retaining their existing iOS settings. Regression control:
in an isolated source/build tree, changing the shared resetOnError option to
true must fail the test. Restore the source and rerun the clean control.