Native mobile standards (iOS / Android)
1. Scope and triggers
Applies to native development: iOS (.swift files, Package.swift, .xcodeproj/
.xcworkspace, Info.plist, .entitlements, SwiftUI) and Android (.kt,
build.gradle.kts, settings.gradle.kts, gradle/libs.versions.toml, AndroidManifest.xml,
Jetpack Compose). Covers code, architecture, build, signing, distribution, security and testing.
Cross-platform (Flutter/RN/KMP-UI) is out of scope except for the native part they touch. Boundary with
dart-standards, mirrored from its §1: the app's design belongs here —architecture,
navigation, platform lifecycle, permissions, publishing on the App Store and Play, signing,
updates, perceived performance, accessibility, secure storage on the device—;
the Dart language and its tooling —pubspec.yaml, analysis_options.yaml, dart format, the lint
sets, build_runner, isolates, the package:test tests— are theirs. Native Swift and Kotlin
still belong here; objective-c-standards covers the Objective-C side of
interoperability with Swift in legacy code. The installable web belongs to pwa-standards:
service worker, manifest, offline cache and the update model. The comparison
of PWA versus native is decided with two facts that neither of the two skills should soften: on iOS
the Push API only works in installed web apps, and a non-installed PWA has no
durable storage —it is subject to ITP eviction—. If the requirement demands store
distribution, hardware capabilities or guaranteed presence, this skill wins.
Not applicable: see jvm-spring-standards (backend Kotlin with Spring: here Kotlin is only the language
of an Android app), typescript-standards (React Native and the web consuming the same API),
api-design-standards (design of the contract the app consumes: resources, codes, pagination,
versioning — here only the HTTP client and error handling on the device), appsec-standards
(threat modelling and agnostic vulnerability classes; here the mobile equivalent is OWASP MASVS
and it does belong to this skill), identity-access-management-standards (OAuth 2.1/OIDC flows, PKCE and
passkeys on the IdP side; here only their use from the device and the storage of the token in
Keychain/Keystore), cryptography-pki-standards (choice of algorithms and certificate pinning as
criteria; here their application with the platform APIs), cicd-standards (the pipeline; the
signing and distribution on the App Store/Play does belong to this skill), observability-standards (telemetry
backend; here crash reporting and client-side metrics), cross-platform-desktop-standards
(the cross-platform desktop is theirs: packaging, signing and notarisation, updates and
integration with the system. Arbitration for Flutter, .NET MAUI and Compose Multiplatform: the
desktop target is decided there, the mobile target and its store, here).
Rule zero: detect the real project first (versions in Package.swift/
libs.versions.toml, minimum targets, existing architecture) and respect its conventions;
this criteria governs what is new and what is flagged as debt.
2. Default toolchain
Verified note: checked via the web on 2026-08-02 (developer.apple.com,
developer.android.com, kotlinlang.org). Verify on the web before pinning versions in a
project: Apple and Google move store and toolchain requirements several times a year.
iOS
- Xcode 26.x (current stable: 26.6) with Swift 6.3; Xcode 27/Swift 6.4 in beta — not for
production until stable. The App Store requires building with SDK iOS 26+ since 2026-04-28.
- Swift 6 language mode (strict concurrency checked by the compiler) in new targets.
- SwiftUI by default for new UI; UIKit only for interoperability or a measured shortcoming.
- Swift Concurrency (
async/await, actors, Sendable) — not Combine nor GCD for new code.
- SPM as the single dependency manager; CocoaPods/Carthage only in legacy, with an exit plan.
- Formatting/lint: swift-format or SwiftLint+SwiftFormat, in CI.
Android
- Kotlin 2.4.x (K2), AGP 9.x (current stable 9.1.1; requires Gradle ≥9.1 and JDK 17;
Kotlin comes integrated in AGP 9 — do not apply
org.jetbrains.kotlin.android separately).
- compileSdk/targetSdk 36 (Android 16): Google Play requires it for new apps and updates from
2026-08-31. Native libraries aligned to 16 KB page size (mandatory on Play since
2026-05-31).
minSdk by audience data, not by convenience.
- Jetpack Compose with a stable BOM (currently
2026.04.01, Compose 1.11) for ALL new UI;
Views/XML maintenance only.
- Coroutines + Flow for asynchrony;
StateFlow for observable state. No
RxJava/AsyncTask/callbacks in new code.
- Gradle version catalogs (
libs.versions.toml) mandatory: zero hardcoded versions in
build.gradle.kts. Convention plugins for multi-module.
- Formatting/lint: ktlint or ktfmt + Android Lint + detekt, in CI.
3. Structure and conventions
Common
- UDF (unidirectional data flow) architecture: declarative UI with no logic; state in an
observable holder; events go up, state comes down. Layers: UI → domain (optional) → data
(repository as the single source of truth).
- Immutability by default (
let/val, struct/data class); mutable state encapsulated.
- Constructor dependency injection: Hilt (Android), manual injection or factories (iOS) —
no global service locators nor mutable singletons.
- Explicit errors: typed
Result/throws on iOS; exceptions/Result + error states
modelled in the UiState on Android. Forbidden to swallow errors (empty catch, silent try?
without a conscious decision).
iOS
- SwiftUI: small, composable views; state with
@State/@Observable (Observation macro,
not ObservableObject in new code); navigation with NavigationStack and typed routes.
- Concurrency: UI on
@MainActor; isolation with actors; shared types Sendable;
@unchecked Sendable forbidden without a documented invariant.
- One SPM module per feature/layer when the project grows; test targets per module.
Android
- Compose: stateless composables (state hoisting),
Modifier as the last parameter with a default,
previews per state (loading/error/empty/content), stability watched (compose compiler
metrics if there is jank).
ViewModel + StateFlow with collectAsStateWithLifecycle; no logic in composables.
- Multi-module per feature (
:feature:x, :core:designsystem, :core:data) when it scales;
api/implementation used properly so as not to leak dependencies.
4. Quality: formatting, lint, static analysis, testing
Blocking CI gates on both platforms — no green, no merge:
- Formatting (swift-format / ktlint) in check mode.
- Lint/static: SwiftLint with no new violations; Android Lint with
lintOptions.abortOnError,
detekt with no issues; compiler warnings treated as errors in our own code
(including Swift 6's strict concurrency checking).
- Unit + UI tests on emulator/simulator; a signable release build.
- Baselines (lint/detekt) only for adoption in legacy: frozen and only ever shrinking.
Testing criteria:
- Pyramid: mostly unit tests over domain/ViewModels/state holders (fast, without an
emulator); just enough integration; few and stable UI/E2E.
- iOS: Swift Testing (
@Test, #expect) for new unit tests, XCTest where it already exists;
XCUITest for critical flows; snapshot tests for high-value SwiftUI views.
- Android: JUnit + Turbine (Flows) + MockK;
runTest with injected dispatchers (the
TestDispatcher rule — never the real Dispatchers.Main in tests); createComposeTestRule for UI;
screenshot tests (Compose Preview Screenshot Testing/Paparazzi) for the design system;
Espresso/instrumentation only for critical E2E flows.
- Cover edges and errors: no network, timeout, malformed response, denied permission, killed
process/state restoration, rotation, dark mode, accessible text sizes.
- Zero flakiness: an unstable test is fixed or deleted; no
sleeps — use idling/waiting on a
condition. Every bugfix leaves a regression test.
5. Stack security (OWASP MASVS as the reference)
- Secure storage: credentials/tokens ONLY in the Keychain (iOS;
kSecAttrAccessibleWhenUnlockedThisDeviceOnly by default, not syncing to iCloud what should
not be) and the Android Keystore (hardware-backed keys; data encrypted with those keys —
EncryptedSharedPreferences is deprecated: encrypt with Keystore + AES-GCM or use DataStore with
your own encryption). FORBIDDEN: tokens in UserDefaults/SharedPreferences/cleartext files, logs
with sensitive data, secrets hardcoded in the binary (they are extracted with strings).
- Network: TLS 1.2+ always; ATS active with no global exceptions (iOS);
networkSecurityConfig
without cleartext (Android). Certificate pinning only with a rotation plan (pin failure = dead
app). Validate ALL input from the server: the backend is also a boundary.
- Signing and distribution:
- iOS: automatic signing managed by Xcode Cloud/fastlane match with certificates in an encrypted
repo or in the CI's manager; distribution keys NEVER in the repo nor on the laptop of
a single person. App Store Connect API keys with the minimum role.
- Android: Play App Signing mandatory (Google holds the signing key; you hold the
upload one, rotatable if compromised). Upload keystore in the CI's secrets manager, never
in the repo;
signingConfig reads from env vars. AAB for Play; signed APK only for
justified direct distribution.
- Publishing through channels: internal → closed → production with gradual rollout and monitoring
of crashes before widening the percentage.
- Permissions and privacy: least privilege, requested in context with justification; Privacy
Manifest (iOS) and Data Safety (Play) truthful and maintained. Personal data: minimisation,
encryption at rest, real deletion on account closure (GDPR).
- SCA and supply chain: pinned dependencies (
Package.resolved and catalog + Gradle lockfile
versioned); Dependabot/Renovate; no abandoned libraries. R8 active in release
(Android); do not disable public symbol stripping without a reason.
- Do not implement homemade crypto: CryptoKit (iOS) / Keystore+AES-GCM or Tink (Android).
SecRandomCopyBytes/SecureRandom for security randomness.
6. Performance and operability
- Startup: measure cold start (Instruments App Launch / Macrobenchmark + Baseline Profiles on
Android — generate and version the baseline profiles); nothing heavy in
application(_:didFinish…)
/ Application.onCreate — defer and initialise lazily (App Startup on Android).
- Smooth UI: no heavy synchronous work on the main thread/composition; in Compose watch
recompositions (stable keys,
derivedStateOf, stable lambdas); in SwiftUI avoid
wide invalidations (granular state with Observation). Lists always lazy with stable ids.
- Memory and energy: Instruments (Leaks/Allocations) and LeakCanary in debug; beware of
strong captures in long-lived closures/lambdas; background work with the system's
APIs (BackgroundTasks / WorkManager with constraints), never your own timers/polling.
- Observability: crash reporting (Crashlytics/Sentry) + MetricKit and Android Vitals as SLIs
(crash-free rate, ANR rate, startup); structured logs without PII; monitor every release
during the gradual rollout and abort if it degrades.
- Offline resilience: the network ALWAYS fails — timeouts, retry with backoff+jitter, local cache
(SwiftData/GRDB, Room) and UI with error/retry states; write operations
idempotent against retries.
- App size watched in CI (app thinning / App Bundle); assets optimised.
7. Sustainability: upgrade cadence and prohibitions
Cadence:
- iOS: adopt the new Xcode/SDK every autumn within <6 months (the App Store turns it into a hard
requirement every spring — in 2026 it was SDK iOS 26 from 28 April). Raise the deployment target
to N-1/N-2 according to the real audience.
- Android: targetSdk at the level Play requires BEFORE the annual deadline of 31 August
(2026: API 36); AGP/Gradle/Kotlin at the pace of stable Android Studio; stable Compose BOM
quarterly.
- Dependencies: Renovate/Dependabot weekly; security patches in <72 h; one toolchain
version per repo (pinned in the catalog/
.xcode-version), not "whichever each machine has".
LIST OF PROHIBITIONS (they block review):
- Secrets, API keys or keystores in the repo or hardcoded in the binary.
- Tokens/credentials outside the Keychain/Keystore; logs with PII or secrets.
- Cleartext HTTP; a global ATS exception; disabling TLS validation "to test".
- iOS:
@unchecked Sendable without a documented invariant; DispatchSemaphore to "wait" on async;
force unwrap (!) and try! outside tests or proven invariants; new ObservableObject in
targets where Observation is available.
- Android: hardcoded versions outside the catalog;
GlobalScope; runBlocking on main;
Dispatchers not injected; disk/network access on the main thread; !! as a style;
EncryptedSharedPreferences in new code (deprecated).
- New UI in UIKit/XML without a written interoperability justification.
- Silencing strict concurrency warnings or lint with suppressions lacking a comment stating the reason.
- Publishing without a test channel or gradual rollout; disabling crash reporting in release.
- WebViews with
javaScriptEnabled + untrusted content, or JS bridges exposed without an allowlist.
- Homemade jailbreak/root detection as the only security control (it is weak mitigation, not a
boundary).
8. Mandatory web verification
Before pinning ANY version or requirement in a real project, verify it on the web:
- Stable Xcode/Swift and the App Store SDK requirement: developer.apple.com/news and Xcode
release notes.
- Google Play requirements (targetSdk, deadlines, 16 KB pages): developer.android.com and Play
Console Help.
- AGP ↔ Gradle ↔ Kotlin ↔ Compose BOM compatibility: official table at
developer.android.com/build/releases and kotlinlang.org/docs/releases.html.
- CVEs of mobile dependencies (GitHub Advisories) before recommending a library.
If the web contradicts this document, the web wins — flag the discrepancy.
1---2name: mobile-standards3description: Native mobile engineering standards for iOS and Android. Use when working with .swift files, SwiftUI, Package.swift, Xcode projects (.xcodeproj/.xcworkspace), Info.plist, or with .kt files, Jetpack Compose, build.gradle.kts, libs.versions.toml, AndroidManifest.xml, or tasks about app signing, distribution, Keychain/Keystore, or mobile testing.4---56# Native mobile standards (iOS / Android)78## 1. Scope and triggers910Applies to native development: **iOS** (`.swift` files, `Package.swift`, `.xcodeproj`/11`.xcworkspace`, `Info.plist`, `.entitlements`, SwiftUI) and **Android** (`.kt`,12`build.gradle.kts`, `settings.gradle.kts`, `gradle/libs.versions.toml`, `AndroidManifest.xml`,13Jetpack Compose). Covers code, architecture, build, signing, distribution, security and testing.14Cross-platform (Flutter/RN/KMP-UI) is out of scope except for the native part they touch. **Boundary with15`dart-standards`, mirrored from its §1**: **the app's design belongs here** —architecture,16navigation, platform lifecycle, permissions, publishing on the App Store and Play, signing,17updates, perceived performance, accessibility, secure storage on the device—;18**the Dart language and its tooling** —`pubspec.yaml`, `analysis_options.yaml`, `dart format`, the lint19sets, `build_runner`, isolates, the `package:test` tests— **are theirs**. Native Swift and Kotlin20still belong here; `objective-c-standards` covers the Objective-C side of21interoperability with Swift in legacy code. **The installable web belongs to `pwa-standards`**:22service worker, manifest, offline cache and the update model. The comparison23of PWA versus native is decided with two facts that **neither of the two skills should soften**: on iOS24the Push API **only works in installed web apps**, and **a non-installed PWA has no25durable storage** —it is subject to ITP eviction—. If the requirement demands store26distribution, hardware capabilities or guaranteed presence, this skill wins.2728**Not applicable**: see `jvm-spring-standards` (backend Kotlin with Spring: here Kotlin is only the language29of an Android app), `typescript-standards` (React Native and the web consuming the same API),30`api-design-standards` (design of the contract the app consumes: resources, codes, pagination,31versioning — here only the HTTP client and error handling on the device), `appsec-standards`32(threat modelling and agnostic vulnerability classes; here the mobile equivalent is OWASP MASVS33and it does belong to this skill), `identity-access-management-standards` (OAuth 2.1/OIDC flows, PKCE and34passkeys on the IdP side; here only their use from the device and the storage of the token in35Keychain/Keystore), `cryptography-pki-standards` (choice of algorithms and certificate pinning as36criteria; here their application with the platform APIs), `cicd-standards` (the pipeline; the37**signing and distribution** on the App Store/Play does belong to this skill), `observability-standards` (telemetry38backend; here crash reporting and client-side metrics), `cross-platform-desktop-standards`39(**the cross-platform desktop is theirs**: packaging, signing and notarisation, updates and40integration with the system. **Arbitration for Flutter, .NET MAUI and Compose Multiplatform: the41desktop target is decided there, the mobile target and its store, here**).4243**Rule zero**: detect the real project first (versions in `Package.swift`/44`libs.versions.toml`, minimum targets, existing architecture) and respect its conventions;45this criteria governs what is new and what is flagged as debt.4647## 2. Default toolchain4849> **Verified note**: checked via the web on 2026-08-02 (developer.apple.com,50> developer.android.com, kotlinlang.org). **Verify on the web before pinning versions** in a51> project: Apple and Google move store and toolchain requirements several times a year.5253**iOS**54- **Xcode 26.x** (current stable: 26.6) with **Swift 6.3**; Xcode 27/Swift 6.4 in beta — not for55 production until stable. The App Store requires building with SDK iOS 26+ since 2026-04-28.56- **Swift 6 language mode** (strict concurrency checked by the compiler) in new targets.57- **SwiftUI** by default for new UI; UIKit only for interoperability or a measured shortcoming.58- **Swift Concurrency** (`async/await`, actors, `Sendable`) — not Combine nor GCD for new code.59- **SPM** as the single dependency manager; CocoaPods/Carthage only in legacy, with an exit plan.60- Formatting/lint: **swift-format** or SwiftLint+SwiftFormat, in CI.6162**Android**63- **Kotlin 2.4.x** (K2), **AGP 9.x** (current stable 9.1.1; requires **Gradle ≥9.1** and JDK 17;64 Kotlin comes integrated in AGP 9 — do not apply `org.jetbrains.kotlin.android` separately).65- **compileSdk/targetSdk 36** (Android 16): Google Play requires it for new apps and updates from66 2026-08-31. Native libraries aligned to **16 KB page size** (mandatory on Play since67 2026-05-31). `minSdk` by audience data, not by convenience.68- **Jetpack Compose** with a **stable BOM** (currently `2026.04.01`, Compose 1.11) for ALL new UI;69 Views/XML maintenance only.70- **Coroutines + Flow** for asynchrony; `StateFlow` for observable state. No71 RxJava/AsyncTask/callbacks in new code.72- **Gradle version catalogs** (`libs.versions.toml`) mandatory: zero hardcoded versions in73 `build.gradle.kts`. Convention plugins for multi-module.74- Formatting/lint: **ktlint** or ktfmt + **Android Lint** + **detekt**, in CI.7576## 3. Structure and conventions7778**Common**79- **UDF (unidirectional data flow)** architecture: declarative UI with no logic; state in an80 observable holder; events go up, state comes down. Layers: UI → domain (optional) → data81 (repository as the single source of truth).82- Immutability by default (`let`/`val`, `struct`/`data class`); mutable state encapsulated.83- Constructor dependency injection: Hilt (Android), manual injection or factories (iOS) —84 no global service locators nor mutable singletons.85- Explicit errors: typed `Result`/`throws` on iOS; exceptions/`Result` + error states86 modelled in the UiState on Android. Forbidden to swallow errors (empty catch, silent `try?`87 without a conscious decision).8889**iOS**90- SwiftUI: small, composable views; state with `@State`/`@Observable` (Observation macro,91 not `ObservableObject` in new code); navigation with `NavigationStack` and typed routes.92- Concurrency: UI on `@MainActor`; isolation with actors; shared types `Sendable`;93 `@unchecked Sendable` forbidden without a documented invariant.94- One SPM module per feature/layer when the project grows; test targets per module.9596**Android**97- Compose: stateless composables (*state hoisting*), `Modifier` as the last parameter with a default,98 previews per state (loading/error/empty/content), stability watched (compose compiler99 metrics if there is jank).100- `ViewModel` + `StateFlow` with `collectAsStateWithLifecycle`; no logic in composables.101- Multi-module per feature (`:feature:x`, `:core:designsystem`, `:core:data`) when it scales;102 `api`/`implementation` used properly so as not to leak dependencies.103104## 4. Quality: formatting, lint, static analysis, testing105106Blocking CI gates on both platforms — no green, no merge:1071. Formatting (swift-format / ktlint) in check mode.1082. Lint/static: SwiftLint with no new violations; Android Lint with `lintOptions.abortOnError`,109 detekt with no issues; **compiler warnings treated as errors** in our own code110 (including Swift 6's strict concurrency checking).1113. Unit + UI tests on emulator/simulator; a signable release build.1124. Baselines (lint/detekt) only for adoption in legacy: frozen and only ever shrinking.113114Testing criteria:115- **Pyramid**: mostly unit tests over domain/ViewModels/state holders (fast, without an116 emulator); just enough integration; few and stable UI/E2E.117- **iOS**: **Swift Testing** (`@Test`, `#expect`) for new unit tests, XCTest where it already exists;118 XCUITest for critical flows; snapshot tests for high-value SwiftUI views.119- **Android**: JUnit + Turbine (Flows) + MockK; `runTest` with injected dispatchers (the120 `TestDispatcher` rule — never the real `Dispatchers.Main` in tests); `createComposeTestRule` for UI;121 screenshot tests (Compose Preview Screenshot Testing/Paparazzi) for the design system;122 Espresso/instrumentation only for critical E2E flows.123- Cover **edges and errors**: no network, timeout, malformed response, denied permission, killed124 process/state restoration, rotation, dark mode, accessible text sizes.125- Zero flakiness: an unstable test is fixed or deleted; no `sleep`s — use idling/waiting on a126 condition. Every bugfix leaves a regression test.127128## 5. Stack security (OWASP MASVS as the reference)129130- **Secure storage**: credentials/tokens ONLY in the **Keychain** (iOS;131 `kSecAttrAccessibleWhenUnlockedThisDeviceOnly` by default, not syncing to iCloud what should132 not be) and the **Android Keystore** (hardware-backed keys; data encrypted with those keys —133 `EncryptedSharedPreferences` is deprecated: encrypt with Keystore + AES-GCM or use DataStore with134 your own encryption). FORBIDDEN: tokens in UserDefaults/SharedPreferences/cleartext files, logs135 with sensitive data, secrets hardcoded in the binary (they are extracted with `strings`).136- **Network**: TLS 1.2+ always; ATS active with no global exceptions (iOS); `networkSecurityConfig`137 without cleartext (Android). Certificate pinning only with a rotation plan (pin failure = dead138 app). Validate ALL input from the server: the backend is also a boundary.139- **Signing and distribution**:140 - iOS: automatic signing managed by Xcode Cloud/fastlane match with certificates in an encrypted141 repo or in the CI's manager; distribution keys NEVER in the repo nor on the laptop of142 a single person. App Store Connect API keys with the minimum role.143 - Android: **Play App Signing** mandatory (Google holds the signing key; you hold the144 upload one, rotatable if compromised). Upload keystore in the CI's secrets manager, never145 in the repo; `signingConfig` reads from env vars. AAB for Play; signed APK only for146 justified direct distribution.147 - Publishing through channels: internal → closed → production with gradual rollout and monitoring148 of crashes before widening the percentage.149- **Permissions and privacy**: least privilege, requested in context with justification; Privacy150 Manifest (iOS) and Data Safety (Play) truthful and maintained. Personal data: minimisation,151 encryption at rest, real deletion on account closure (GDPR).152- **SCA and supply chain**: pinned dependencies (`Package.resolved` and catalog + Gradle lockfile153 versioned); Dependabot/Renovate; no abandoned libraries. R8 active in release154 (Android); do not disable public symbol *stripping* without a reason.155- Do not implement homemade crypto: CryptoKit (iOS) / Keystore+AES-GCM or Tink (Android).156 `SecRandomCopyBytes`/`SecureRandom` for security randomness.157158## 6. Performance and operability159160- **Startup**: measure cold start (Instruments App Launch / Macrobenchmark + Baseline Profiles on161 Android — generate and version the baseline profiles); nothing heavy in `application(_:didFinish…)`162 / `Application.onCreate` — defer and initialise lazily (App Startup on Android).163- **Smooth UI**: no heavy synchronous work on the main thread/composition; in Compose watch164 recompositions (stable keys, `derivedStateOf`, stable lambdas); in SwiftUI avoid165 wide invalidations (granular state with Observation). Lists always lazy with stable ids.166- **Memory and energy**: Instruments (Leaks/Allocations) and LeakCanary in debug; beware of167 strong captures in long-lived closures/lambdas; background work with the system's168 APIs (BackgroundTasks / WorkManager with constraints), never your own timers/polling.169- **Observability**: crash reporting (Crashlytics/Sentry) + MetricKit and Android Vitals as SLIs170 (crash-free rate, ANR rate, startup); structured logs without PII; monitor every release171 during the gradual rollout and abort if it degrades.172- **Offline resilience**: the network ALWAYS fails — timeouts, retry with backoff+jitter, local cache173 (SwiftData/GRDB, Room) and UI with error/retry states; write operations174 idempotent against retries.175- App size watched in CI (app thinning / App Bundle); assets optimised.176177## 7. Sustainability: upgrade cadence and prohibitions178179**Cadence**:180- **iOS**: adopt the new Xcode/SDK every autumn within <6 months (the App Store turns it into a hard181 requirement every spring — in 2026 it was SDK iOS 26 from 28 April). Raise the deployment target182 to N-1/N-2 according to the real audience.183- **Android**: targetSdk at the level Play requires BEFORE the annual deadline of 31 August184 (2026: API 36); AGP/Gradle/Kotlin at the pace of stable Android Studio; stable Compose BOM185 quarterly.186- Dependencies: Renovate/Dependabot weekly; security patches in <72 h; one toolchain187 version per repo (pinned in the catalog/`.xcode-version`), not "whichever each machine has".188189**LIST OF PROHIBITIONS** (they block review):190- Secrets, API keys or keystores in the repo or hardcoded in the binary.191- Tokens/credentials outside the Keychain/Keystore; logs with PII or secrets.192- Cleartext HTTP; a global ATS exception; disabling TLS validation "to test".193- iOS: `@unchecked Sendable` without a documented invariant; `DispatchSemaphore` to "wait" on async;194 force unwrap (`!`) and `try!` outside tests or proven invariants; new `ObservableObject` in195 targets where Observation is available.196- Android: hardcoded versions outside the catalog; `GlobalScope`; `runBlocking` on main;197 `Dispatchers` not injected; disk/network access on the main thread; `!!` as a style;198 `EncryptedSharedPreferences` in new code (deprecated).199- New UI in UIKit/XML without a written interoperability justification.200- Silencing strict concurrency warnings or lint with suppressions lacking a comment stating the reason.201- Publishing without a test channel or gradual rollout; disabling crash reporting in release.202- WebViews with `javaScriptEnabled` + untrusted content, or JS bridges exposed without an allowlist.203- Homemade jailbreak/root detection as the only security control (it is weak mitigation, not a204 boundary).205206## 8. Mandatory web verification207208Before pinning ANY version or requirement in a real project, **verify it on the web**:209- Stable Xcode/Swift and the App Store SDK requirement: developer.apple.com/news and Xcode210 release notes.211- Google Play requirements (targetSdk, deadlines, 16 KB pages): developer.android.com and Play212 Console Help.213- AGP ↔ Gradle ↔ Kotlin ↔ Compose BOM compatibility: official table at214 developer.android.com/build/releases and kotlinlang.org/docs/releases.html.215- CVEs of mobile dependencies (GitHub Advisories) before recommending a library.216217If the web contradicts this document, **the web wins** — flag the discrepancy.