Final step of the debug-logging strangler epic #324: a detekt style > ForbiddenImport rule that fails the build on any import android.util.Log outside the AppLog facade, so nothing can bypass the debug-report RingLogBuffer (raw android.util.Log writes to Logcat only and never reaches a user-reviewed DebugReport).
Rule
config/detekt/detekt.yml → style > ForbiddenImport, forbidding android.util.Log with a reason pointing devs to org.libremail.reporting.AppLog. Note: detekt 2.0.0-alpha.5 renamed the rule's old imports key to forbiddenImports (allowed props: active, allowedImports, forbiddenImports) — the config uses the new key. Import-based, so no type resolution needed.
Excludes (rule-level excludes: globs)
**/reporting/AppLog.kt — the one sanctioned wrapper; it is the facade.
Unit tests that mockkStatic(Log) only to mock/verify forwarding — they don't bypass the facade. AppLog forwards to android.util.Log, a throwing stub under plain JVM unit tests, so any test exercising AppLog-logging code must mock Log: the two facade tests (AppLogTest, AppLogUninstalledTest), RestartActivityLoggingTest, the sync-engine tests (SyncWorkerTest, MailSyncerTest, MailBackfillerTest, MailPrunerTest, MailMaintenanceGateTest, MailSyncConcurrencyTest, PruneWorkerTest, BackfillWorkerTest), and the auth/lock tests (AppLockViewModelTest, AccountSetupViewModelTest).
No production file is excluded — production code must migrate to AppLog.
Depends on #340/#326 — detekt flags the 2 auth/lock files (AppLockViewModel, AccountSetupViewModel) until #340 merges; those are #340's job to migrate, not this PR's. Validated the guard reaches 0 findings with all migrations present (temp-merged feat-326: :app:detekt → BUILD SUCCESSFUL, then discarded so this PR is config-only). Greens via auto-update once #340 lands.
Final step of the debug-logging strangler epic #324: a detekt `style > ForbiddenImport` rule that fails the build on any `import android.util.Log` outside the `AppLog` facade, so nothing can bypass the debug-report `RingLogBuffer` (raw `android.util.Log` writes to Logcat only and never reaches a user-reviewed `DebugReport`).
## Rule
`config/detekt/detekt.yml` → `style > ForbiddenImport`, forbidding `android.util.Log` with a `reason` pointing devs to `org.libremail.reporting.AppLog`. Note: detekt 2.0.0-alpha.5 renamed the rule's old `imports` key to `forbiddenImports` (allowed props: `active, allowedImports, forbiddenImports`) — the config uses the new key. Import-based, so no type resolution needed.
## Excludes (rule-level `excludes:` globs)
- `**/reporting/AppLog.kt` — the one sanctioned wrapper; it **is** the facade.
- Unit tests that `mockkStatic(Log)` only to mock/verify forwarding — they don't bypass the facade. `AppLog` forwards to `android.util.Log`, a throwing stub under plain JVM unit tests, so any test exercising AppLog-logging code must mock `Log`: the two facade tests (`AppLogTest`, `AppLogUninstalledTest`), `RestartActivityLoggingTest`, the sync-engine tests (`SyncWorkerTest`, `MailSyncerTest`, `MailBackfillerTest`, `MailPrunerTest`, `MailMaintenanceGateTest`, `MailSyncConcurrencyTest`, `PruneWorkerTest`, `BackfillWorkerTest`), and the auth/lock tests (`AppLockViewModelTest`, `AccountSetupViewModelTest`).
No production file is excluded — production code must migrate to `AppLog`.
## Dependency — draft until #340 lands
Depends on #340/#326 — detekt flags the 2 auth/lock files (`AppLockViewModel`, `AccountSetupViewModel`) until #340 merges; those are #340's job to migrate, not this PR's. Validated the guard reaches **0 findings** with all migrations present (temp-merged `feat-326`: `:app:detekt` → BUILD SUCCESSFUL, then discarded so this PR is config-only). Greens via auto-update once #340 lands.
Closes #331
Part of #324
🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.
Final step of the debug-logging strangler epic #324: a detekt
style > ForbiddenImportrule that fails the build on anyimport android.util.Logoutside theAppLogfacade, so nothing can bypass the debug-reportRingLogBuffer(rawandroid.util.Logwrites to Logcat only and never reaches a user-reviewedDebugReport).Rule
config/detekt/detekt.yml→style > ForbiddenImport, forbiddingandroid.util.Logwith areasonpointing devs toorg.libremail.reporting.AppLog. Note: detekt 2.0.0-alpha.5 renamed the rule's oldimportskey toforbiddenImports(allowed props:active, allowedImports, forbiddenImports) — the config uses the new key. Import-based, so no type resolution needed.Excludes (rule-level
excludes:globs)**/reporting/AppLog.kt— the one sanctioned wrapper; it is the facade.mockkStatic(Log)only to mock/verify forwarding — they don't bypass the facade.AppLogforwards toandroid.util.Log, a throwing stub under plain JVM unit tests, so any test exercising AppLog-logging code must mockLog: the two facade tests (AppLogTest,AppLogUninstalledTest),RestartActivityLoggingTest, the sync-engine tests (SyncWorkerTest,MailSyncerTest,MailBackfillerTest,MailPrunerTest,MailMaintenanceGateTest,MailSyncConcurrencyTest,PruneWorkerTest,BackfillWorkerTest), and the auth/lock tests (AppLockViewModelTest,AccountSetupViewModelTest).No production file is excluded — production code must migrate to
AppLog.Dependency — draft until #340 lands
Depends on #340/#326 — detekt flags the 2 auth/lock files (
AppLockViewModel,AccountSetupViewModel) until #340 merges; those are #340's job to migrate, not this PR's. Validated the guard reaches 0 findings with all migrations present (temp-mergedfeat-326::app:detekt→ BUILD SUCCESSFUL, then discarded so this PR is config-only). Greens via auto-update once #340 lands.Closes #331
Part of #324
🤖 Generated with Claude Code