| Build fails with an error string you can quote | Match the string first; most Android build errors are one of a dozen | build-failures.md |
| Build is slow, cache never hits, or a dependency resolves to the wrong version | Configuration cache, layer the modules, then dependencyInsight on the winner | gradle.md |
Raising targetSdk or compileSdk | Behavior changes apply the moment targetSdk crosses the level (→ Target SDK Breakage) | sdk-upgrades.md |
adb cannot see the device, or install fails | Decode the INSTALL_FAILED_* string; it names the cause exactly | devices.md |
| Compose recomposes too much, loses state, or a list janks | Deferred reads, stable parameters, key on list items | compose.md |
| XML layouts, Fragments, RecyclerView, or interop with Compose | ViewBinding, viewLifecycleOwner, ListAdapter + DiffUtil | views.md |
| State lost on rotation, or after the app sat in the background | Three tiers: recomposition, config change, process death (Rule 4) | lifecycle.md |
| "Where does this code go", DI wiring, or a Flow that emits wrong | Layering, Hilt/Koin, stateIn + repeatOnLifecycle | architecture.md |
| Room migration, DataStore, files, or a query on the main thread | Migration test first, then fallbackToDestructiveMigration never | data.md |
| Background work never runs, is late, or the service crashes at start | Guaranteed-eventually vs user-visible-now vs exact (Rule 6) | background.md |
| Permission denied with no dialog, or scoped storage blocks a file | Rationale state machine, then the policy-restricted list | permissions.md |
| Requests fail on device but succeed from the terminal | Cleartext policy, then DNS/proxy, then pinning, then timeouts | networking.md |
| Reproducing a bug on a device, or instrumenting one | logcat --pid, dumpsys, StrictMode, forced Doze, deep-link intents | debug.md |
| A crash or ANR reported from the field | Deobfuscate, cluster by signature, then match the ANR timeout | crashes.md |
| Slow cold start, jank, oversized bundle, or memory growth | Measure with the macrobenchmark before changing anything | performance.md |
| Tests flake, or instrumented tests need a device | Animations off, dispatcher injected, orchestrator with clearPackageData | testing.md |
| Signing, keystore, R8 keep rules, versionCode, building the AAB | Upload key vs app signing key; mapping file per versionCode | release.md |
| Play rejection, staged rollout, tracks, declarations, vitals | The declaration forms are the rejection surface, not the code | play-console.md |
| Build, sign, or upload from CI | Keystore as a decoded secret, Gradle cache, emulator with KVM | ci.md |
| Foldables, tablets, Wear, TV, Auto, or an OEM-only bug | Window size classes, and the OEM battery ladder for background bugs | devices.md |
| Exported components, WebView, backup, deep-link hijack, secrets in the APK | Nothing in the APK is a secret (Rule 7); everything else is attack surface | security.md |
| Anything else Android | Name the layer — build, install, runtime, store — then reproduce on one device with one variable changed at a time | — |