android_conformance_test.zig checks that every native android_dispatch.zig registers has a matching external fun name in CraftNative.kt, and the reverse. It does not compare the JNI descriptor with the Kotlin parameter and return types.
A descriptor that disagrees with its external fun makes RegisterNatives refuse the whole table. Every action then falls back to Kotlin: the shim leg still passes, and only the runtime E2E leg notices, as a missing registered 103 natives line, after a full emulator run. #215 changed one descriptor, nativeDispatchDeepLink to (Ljava/lang/String;Z)Z, and pinned that one string in a Zig test. Only CI could show that it matches the Kotlin.
Suggested: parse each external fun name(params): Return in CraftNative.kt, map the handful of types the file uses to descriptor letters, and compare with natives:
Activity→Landroid/app/Activity;String/String?→Ljava/lang/String;Boolean→ZInt→IByteArray→[BWebViewIntentSenderUnit→V
This makes the whole class of mismatch a local test failure.