Migrates data/security/DatabaseKeyCipher (4 sites), data/local/DatabaseEncryption (1 site), and data/local/AccountDataMigrator (1 site) off raw android.util.Log onto AppLog (seam from #325), so these breadcrumbs reach the process RingLogBuffer (and a user-reviewed debug report) even in release builds, where Log.d is otherwise stripped from Logcat only.
Adds the new DatabaseEncryption.migrate start breadcrumb the ticket calls for: AppLog.i(TAG, "converting local cache database (targetEncrypted=...)"), alongside the existing "converted" completion line now routed through AppLog.d.
AccountDataMigrator's "moved account tables into the account database: $present" breadcrumb (table names only) now routed through AppLog.d.
DatabaseKeyCipher's 4 auth-bound-key decision points (encrypt's invalidated-key retry, and isInvalidated's three branches) now log via AppLog.d(tag, msg, e).
PII: none logged. Keystore exceptions, a set of table names, and a boolean flag only — never the passphrase, key material, or an account address/host.
Test plan
Extended DatabaseEncryptionTest (instrumented — loads the real SQLCipher native lib) with conversionEmitsNonPiiAppLogBreadcrumbs: installs a RingLogBuffer, round-trips a seeded DB (with a real email address) through ensureEncrypted/ensurePlaintext, and asserts the "converting…"/"converted" breadcrumbs land with the right levels (I/D) and never contain the passphrase, the db file path, or the seeded email.
Extended AccountDataMigratorTest with copyEmitsANonPiiAppLogBreadcrumbNamingOnlyTheMovedTables: installs a RingLogBuffer, runs copyAccountTables, and asserts the breadcrumb names every moved table and never contains the seeded email, secret, or passphrase.
DatabaseKeyCipher stays device-only and behavior-preserving (auth-bound Keystore keys/BiometricPrompt can't run off-device); its migration is compile-verified, and the breadcrumb-reaches-buffer guarantee at the AppLog.d(throwable) level is already unit-tested in the #325 seam.
:app:testDebugUnitTest:app:compileDebugAndroidTestKotlin:app:ktlintCheck:app:detekt all green locally.
The two new instrumented tests were not run on an emulator in this pass (dispatched as a unit-only validation to avoid concurrent local emulators); CI's full matrix will execute them before merge.
## Summary
- Migrates `data/security/DatabaseKeyCipher` (4 sites), `data/local/DatabaseEncryption` (1 site), and `data/local/AccountDataMigrator` (1 site) off raw `android.util.Log` onto `AppLog` (seam from #325), so these breadcrumbs reach the process `RingLogBuffer` (and a user-reviewed debug report) even in release builds, where `Log.d` is otherwise stripped from Logcat only.
- Adds the new `DatabaseEncryption.migrate` start breadcrumb the ticket calls for: `AppLog.i(TAG, "converting local cache database (targetEncrypted=...)")`, alongside the existing "converted" completion line now routed through `AppLog.d`.
- `AccountDataMigrator`'s "moved account tables into the account database: $present" breadcrumb (table names only) now routed through `AppLog.d`.
- `DatabaseKeyCipher`'s 4 auth-bound-key decision points (encrypt's invalidated-key retry, and `isInvalidated`'s three branches) now log via `AppLog.d(tag, msg, e)`.
- PII: none logged. Keystore exceptions, a set of table names, and a boolean flag only — never the passphrase, key material, or an account address/host.
## Test plan
- [x] Extended `DatabaseEncryptionTest` (instrumented — loads the real SQLCipher native lib) with `conversionEmitsNonPiiAppLogBreadcrumbs`: installs a `RingLogBuffer`, round-trips a seeded DB (with a real email address) through `ensureEncrypted`/`ensurePlaintext`, and asserts the "converting…"/"converted" breadcrumbs land with the right levels (`I`/`D`) and never contain the passphrase, the db file path, or the seeded email.
- [x] Extended `AccountDataMigratorTest` with `copyEmitsANonPiiAppLogBreadcrumbNamingOnlyTheMovedTables`: installs a `RingLogBuffer`, runs `copyAccountTables`, and asserts the breadcrumb names every moved table and never contains the seeded email, secret, or passphrase.
- [x] `DatabaseKeyCipher` stays device-only and behavior-preserving (auth-bound Keystore keys/BiometricPrompt can't run off-device); its migration is compile-verified, and the breadcrumb-reaches-buffer guarantee at the `AppLog.d(throwable)` level is already unit-tested in the #325 seam.
- [x] `:app:testDebugUnitTest` `:app:compileDebugAndroidTestKotlin` `:app:ktlintCheck` `:app:detekt` all green locally.
- [ ] The two new instrumented tests were not run on an emulator in this pass (dispatched as a unit-only validation to avoid concurrent local emulators); CI's full matrix will execute them before merge.
Closes #327
Part of #324
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Summary
data/security/DatabaseKeyCipher(4 sites),data/local/DatabaseEncryption(1 site), anddata/local/AccountDataMigrator(1 site) off rawandroid.util.LogontoAppLog(seam from #325), so these breadcrumbs reach the processRingLogBuffer(and a user-reviewed debug report) even in release builds, whereLog.dis otherwise stripped from Logcat only.DatabaseEncryption.migratestart breadcrumb the ticket calls for:AppLog.i(TAG, "converting local cache database (targetEncrypted=...)"), alongside the existing "converted" completion line now routed throughAppLog.d.AccountDataMigrator's "moved account tables into the account database: $present" breadcrumb (table names only) now routed throughAppLog.d.DatabaseKeyCipher's 4 auth-bound-key decision points (encrypt's invalidated-key retry, andisInvalidated's three branches) now log viaAppLog.d(tag, msg, e).Test plan
DatabaseEncryptionTest(instrumented — loads the real SQLCipher native lib) withconversionEmitsNonPiiAppLogBreadcrumbs: installs aRingLogBuffer, round-trips a seeded DB (with a real email address) throughensureEncrypted/ensurePlaintext, and asserts the "converting…"/"converted" breadcrumbs land with the right levels (I/D) and never contain the passphrase, the db file path, or the seeded email.AccountDataMigratorTestwithcopyEmitsANonPiiAppLogBreadcrumbNamingOnlyTheMovedTables: installs aRingLogBuffer, runscopyAccountTables, and asserts the breadcrumb names every moved table and never contains the seeded email, secret, or passphrase.DatabaseKeyCipherstays device-only and behavior-preserving (auth-bound Keystore keys/BiometricPrompt can't run off-device); its migration is compile-verified, and the breadcrumb-reaches-buffer guarantee at theAppLog.d(throwable)level is already unit-tested in the #325 seam.:app:testDebugUnitTest:app:compileDebugAndroidTestKotlin:app:ktlintCheck:app:detektall green locally.Closes #327
Part of #324
🤖 Generated with Claude Code
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com