#!/usr/bin/env bash # Static Phase-0 safety regression checks for code that needs Android/JNI or # Makepad integration and therefore cannot be covered by the pure Rust tests. set -Eeuo pipefail ROOT="$(CDPATH= cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)" SESSION="$ROOT/crates/robius-ussd/src/sys/android/session.rs" SERVICE="$ROOT/crates/robius-ussd/src/sys/android/UssdAccessibilityService.java" USSD_LIB="$ROOT/crates/robius-ussd/src/lib.rs" FP_LIB="$ROOT/crates/robius-fingerprinting/src/lib.rs" STORE="$ROOT/crates/nigig-core/src/persistence/mpesa/store.rs" # PIN must never cross Rust -> SharedPreferences. if grep -Eq 'put_string\([^\n]*KEY_PIN' "$SESSION"; then echo "Phase-0 failure: Rust still writes KEY_PIN to SharedPreferences" >&2 exit 1 fi # The Android automation service must fail closed instead of reading/typing it. if ! grep -Fq 'fail("pin_handoff_disabled")' "$SERVICE"; then echo "Phase-0 failure: Android PIN state is not fail-closed" >&2 exit 1 fi if grep -Eq 'getString\(KEY_PIN' "$SERVICE"; then echo "Phase-0 failure: Android service still reads KEY_PIN" >&2 exit 1 fi # Dummy successful events must be test-only APIs. for source in "$USSD_LIB" "$FP_LIB"; do if grep -n 'pub fn dummy_' "$source" | grep -vq 'cfg'; then # The cfg is on the preceding line; validate structurally below. : fi done if ! grep -B2 -Fq 'pub fn dummy_session_events' "$USSD_LIB" || \ ! grep -B2 -Fq 'feature = "test-support"' "$USSD_LIB"; then echo "Phase-0 failure: USSD dummy events are not test-support gated" >&2 exit 1 fi if ! grep -B2 -Fq 'pub fn dummy_success' "$FP_LIB" || \ ! grep -B2 -Fq 'feature = "test-support"' "$FP_LIB"; then echo "Phase-0 failure: fingerprint dummy success is not test-support gated" >&2 exit 1 fi # The default tracker persistence must not write full raw SMS bodies. if ! grep -Fq 'raw_message intentionally omitted' "$STORE"; then echo "Phase-0 failure: tracker store no longer documents raw SMS omission" >&2 exit 1 fi echo "payment Phase-0 safety checks passed"