# Delta 0.3.3-0-pre.2 ## Base et statut précédent Cette tranche part exclusivement de `0.3.3-0-pre.1` validé par l'utilisateur le 2026-09-21. `history/0.3.3/0-pre.1.md` enregistre la gate propre et l'inventaire Android réellement observé avant ouverture du développement productif. Aucun fix de `0-pre.1` n'est requis. ## Objectif Prouver sur Snake Debug et une seule ABI que Gradle possède désormais la chaîne native complète : ```text :game-snake-poc:assembleDebug -> source jniLibs générée par AGP Variant API -> extraction de libSDL3.so depuis l'AAR -> résolution du NDK projet r28c -> cargo ndk arm64-v8a -> feature snake uniquement -> libSDL3.so + libgame_android_entrypoint.so -> APK Debug ARM64 ``` La commande normale ne dépend plus d'un appel préalable à `scripts/build_android_rust.py snake`. ## Gradle Wrapper reproductible Le projet Android reçoit le wrapper Gradle et l'épingle à `9.6.0`, version attendue par AGP `9.4.0` dans le cadrage `0-pre.1`. Contrats de chaîne d'approvisionnement : ```text Gradle 9.6.0 binary ZIP SHA-256 bbaeb2fef8710818cf0e261201dab964c572f92b942812df0c3620d62a529a01 Gradle Wrapper JAR SHA-256 497c8c2a7e5031f6aa847f88104aa80a93532ec32ee17bdb8d1d2f67a194a9c7 ``` `validateDistributionUrl=true` reste activé. L'audit de distribution vérifie statiquement ces contrats. Le wrapper respecte `JAVA_HOME`; l'environnement utilisateur validé expose JDK 17 via cette variable même si `java` dans le `PATH` pointe vers JDK 25. ## Ownership Gradle/Cargo `Android/gradle/sasedev-rust-android.gradle` introduit une tâche native incrémentale par ABI. Ses inputs comprennent l'AAR SDL3, les manifests/configurations Cargo utiles, le code Rust, la feature, l'ABI, l'API Android et la version NDK. Son output est un répertoire `jniLibs` généré sous `build/generated/sasedevNative/...`. La tâche : 1. extrait `libSDL3.so` depuis Prefab ou le fallback AAR compatible ; 2. résout `${ANDROID_HOME}/ndk/28.2.13676358` ou l'équivalent `ANDROID_SDK_ROOT` ; 3. définit `ANDROID_NDK_HOME`, `CARGO_NDK_PLATFORM=21` et le chemin de linkage SDL3 uniquement pour le sous-processus ; 4. lance `cargo ndk` sans defaults avec la seule feature Snake ; 5. vérifie les deux `.so` attendus ; 6. remet l'output à `variant.sources.jniLibs.addGeneratedSourceDirectory`, qui crée la dépendance de build AGP. Aucun nouvel orchestrateur Python ou shell spécifique au projet n'est introduit. ## Borne mono-ABI `game-snake-poc` fixe volontairement : ```text feature snake ABI arm64-v8a API Rust 21 ``` et `ndk.abiFilters 'arm64-v8a'` empêche ce jalon de masquer une erreur de task wiring derrière le packaging d'autres ABI. `x86_64` reste pour `0-pre.3` après validation réelle de cette preuve ARM64. Reflex n'est pas modifié dans cette tranche. ## Audit de distribution `scripts/audit_distribution_layout.py` exige désormais les cinq nouveaux éléments durables du pipeline : ```text Android/gradlew Android/gradlew.bat Android/gradle/wrapper/gradle-wrapper.jar Android/gradle/wrapper/gradle-wrapper.properties Android/gradle/sasedev-rust-android.gradle ``` Il contrôle également le checksum du JAR wrapper, la distribution 9.6.0, l'absence de délégation Python dans le nouveau build natif et le contrat mono-ABI Snake. ## Fichiers Ajoutés : ```text Android/gradlew Android/gradlew.bat Android/gradle/sasedev-rust-android.gradle Android/gradle/wrapper/gradle-wrapper.jar Android/gradle/wrapper/gradle-wrapper.properties deltas/0.3.3/0-pre.2.md history/0.3.3/0-pre.1.md ``` Modifiés : ```text Android/README.md Android/game-snake-poc/build.gradle Cargo.toml docs/development/006-ANDROID_RUST_NATIVE_BUILD.md scripts/audit_distribution_layout.py ``` `scripts/build_android_rust.py`, Reflex, les sources Rust, `CHANGELOG.md` et `ROADMAP.md` restent inchangés. ## Validations exécutées dans l'environnement de génération Le générateur exécute uniquement les audits statiques autorisés après constitution du delta : ```bash python3 scripts/audit_rust_workspace_rules.py python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates Android Web deltas history python3 scripts/audit_distribution_layout.py ``` Aucun build Cargo/Gradle, test ou smoke final n'est attribué au générateur. ## Validation utilisateur demandée Depuis la racine : ```bash export JAVA_HOME=/usr/lib/jvm/temurin-17-jdk-amd64 python3 scripts/audit_rust_workspace_rules.py python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates Android Web deltas history python3 scripts/audit_distribution_layout.py cargo fmt --all cargo fmt --all -- --check cargo check --workspace cargo clippy --workspace --all-targets --all-features -- -D warnings sha256sum Android/gradle/wrapper/gradle-wrapper.jar grep -E '^(distributionUrl|distributionSha256Sum|validateDistributionUrl)=' Android/gradle/wrapper/gradle-wrapper.properties (cd Android && ./gradlew --version) (cd Android && ./gradlew :game-snake-poc:assembleDebug) ``` Le build Snake doit être lancé directement : ne pas appeler `scripts/build_android_rust.py snake` avant Gradle. Puis inspecter l'APK produit : ```bash APK="$(find Android/game-snake-poc/build/outputs/apk/debug -maxdepth 1 -type f -name '*.apk' -print -quit)" test -n "$APK" printf 'APK=%s\n' "$APK" unzip -Z1 "$APK" | grep '^lib/' | sort unzip -Z1 "$APK" | grep -Fx 'lib/arm64-v8a/libSDL3.so' unzip -Z1 "$APK" | grep -Fx 'lib/arm64-v8a/libgame_android_entrypoint.so' if unzip -Z1 "$APK" | grep -Eq '^lib/(x86_64|armeabi-v7a|x86)/'; then printf '%s\n' 'unexpected non-ARM64 native library in mono-ABI proof' >&2 exit 1 fi ``` Le checksum attendu du wrapper JAR est : ```text 497c8c2a7e5031f6aa847f88104aa80a93532ec32ee17bdb8d1d2f67a194a9c7 ``` Aucun smoke appareil n'est requis dans cette tranche ; il reste planifié après établissement du packaging multi-ABI. ## Suite après validation Si cette gate est propre, `0-pre.3` crée `history/0.3.3/0-pre.2.md`, étend le même ownership à `arm64-v8a + x86_64`, exige un APK Debug universal contenant les deux couples de bibliothèques et migre Reflex uniquement si la factorisation commune reste naturelle. Une erreur de wrapper, de task wiring, de linkage SDL3, de feature Cargo ou de contenu APK produit d'abord `0-pre.2.fix.N`.