Skip to content

📌 apps: every app runs the SDK snapshots built on kamera 1.2.1-SNAPSHOT.34 and njia 0.0.1-SNAPSHOT.11 - #259

Merged
Juma Allan (jumaallan) merged 1 commit into
mainfrom
chore/repin-v12-njia-11
Oct 26, 2026
Merged

Juma Allan (jumaallan) merged 1 commit into
mainfrom
chore/repin-v12-njia-11

Conversation

@jumaallan

@jumaallan Juma Allan (jumaallan) commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

User description

Story: N/A. The four SDKs now build on kamera 1.2.1-SNAPSHOT.34 and njia 0.0.1-SNAPSHOT.11 (android#704, ios-v12#606, flutter#479, react-native-expo#523), and they carry round 4's changes: a flow sends its job once, every SDK reaches the same validation verdict, and validate() now returns the verdict build() reaches. This moves all four apps to those snapshots and follows the validation change in the apps' preflight.

Summary

  • Android: the SDK artifacts go to the 12.3.0-20261026.002955 snapshot (built after android#704), and njia to 0.0.1-20261025.232953-11.
  • iOS: ios-spm goes to 12.3.0-SNAPSHOT.20261026003357.40248619993 (after ios-v12#606), and Njia to 0.0.1-SNAPSHOT.11. SampleUI/Package.resolved takes kamera-spm 1.2.1-SNAPSHOT.34, and licenses.json is regenerated.
  • Flutter: the SDK packages go to 12.3.1-SNAPSHOT.25, and usesmileid_njia and -testing to 0.0.1-SNAPSHOT.11. That covers pubspec.lock and the app's two Package.resolved files.
  • Expo: the SDK packages go to 12.3.1-SNAPSHOT.71 (app and sample UI), and @smileid/njia and -testing to 0.0.1-SNAPSHOT.11, with pnpm-lock.yaml.
  • Preflight follows the SDK:
    • validate() now returns build()'s verdict, so the Android and iOS preflight sees refusals it used to miss: a flow with no consent, agent mode with enhanced liveness, and the Green Book on Enhanced Document Verification.
    • On both, a refused flow now lands where the SDK's own Failure does, on the unsubmitted job's details with the reason. Before, it returned to the product list, which reads as a dead tap.
    • SdkFlowPreflightTest asserts those refusals, and runs under Robolectric because the SDK now reads the token's bindings with android.util.Base64.
    • Flutter's host test calls validate() and matches the exported ValidationState, instead of reading the type name of build()'s internal result.
  • android/verify.sh names the app's real ids in its Maestro hint, and the plan doc and test comments now say what validate() checks today.

Known Issues

  • Locally, 329 of the Expo sample UI's pixel goldens differ by a few dozen pixels, on main exactly as on this branch. CI's goldens are the ones that count.
  • In the full iOS UI run, 2 launch-argument tests failed (testAnUnrecognisedValueReadsAsTheDefaultOnTheCard, testAPlainLaunchHasNoProfile). Run alone, that class passes 2 of 2 times on this branch and 2 of 2 on main: a load flake, not this change.
  • The Flutter app's Maestro flows can't run on an iOS simulator, because a Flutter debug build exits when it's launched without the flutter tool attached. CI runs them on Android only. iOS was driven by hand instead (below).
  • The Expo flows on an iOS simulator stop at iOS's "Open in UseSmileID Sample (Expo)?" prompt, which iOS raises for a custom-scheme deep link. CI runs those flows on Android only, so the iOS app was driven by hand too.

Test Instructions

Device runs, Oct 25, on the smileid-local-ci emulator (API 34) and iOS 27.0 simulators:

  • Android app, emulator: all 10 Maestro flows pass (android/maestro): settings, token-session, deep-links, shell-navigation, launch-args, profiles, sdk-flow, profile-journey, verifications and document-options. settings failed on this branch before the preflight change, at its consent step, where the refused flow must land on the job's details. It passes now and passes on main.
  • iOS app, simulator: ios/verify.sh all runs tokens, notices, format, the library unit tests, the goldens, the shell unit tests and the navigation UI suite. Every phase passes, except the 2 launch-argument flakes above.
  • Flutter app, emulator: all 8 Maestro flows pass (flutter/maestro, release APK).
  • Flutter app, iOS simulator, driven by hand: the app went from the product list through Registration, the simulated token scan and the details form to the SDK's consent screen. Allow then led to the SDK's selfie instructions on the new snapshot.
  • Expo app, emulator: all 4 Maestro flows pass (expo/maestro, release APK).
  • Expo app, iOS simulator, driven by hand (release build): the app went from the product list through Document Verification, the simulated token scan, the details form, and Afghanistan with Passport to the SDK's consent screen. Allow then led to the SDK's passport capture instructions.
  • flutter/verify.sh checks passes. The Expo app's 512 unit tests pass.

Screenshot

N/A

📌


PR Type

Enhancement, Tests


Description

  • Repin all four apps to new SDK snapshots

    • Android, iOS, Flutter and Expo SDK builds now sit on kamera 1.2.1-SNAPSHOT.34
    • njia moves to 0.0.1-SNAPSHOT.11 on every platform
  • Refused flows land on unsubmitted job details

    • Android SdkFlowScreen.kt and iOS SdkFlowScreen.swift route Misconfigured to VerificationDetails with UNSUBMITTED_JOB_ID
    • These no longer return silently to the product list
  • Tests follow validate() returning build()'s verdict

    • Android preflight test runs under Robolectric and covers new refusals
    • Flutter test uses the public validate() instead of the internal build()
  • Comments, docs and Maestro notes updated; verify.sh app ids fixed


Diagram Walkthrough

flowchart LR
  pins["SDK snapshots (kamera .34, njia .11)"]
  validate["validate() returns build() verdict"]
  preflight["Android/iOS preflight"]
  details["Unsubmitted job details screen"]
  tests["Preflight & flow-host tests"]
  pins -- "ship" --> validate
  validate -- "seen by" --> preflight
  preflight -- "Misconfigured lands on" --> details
  validate -- "asserted in" --> tests
Loading

File Walkthrough

Relevant files
Tests
2 files
use_smileid_sample_flow_host_test.dart
Assert configurations through public validate() instead of build()
+32/-35 
SdkFlowPreflightTest.kt
Robolectric preflight tests for agent-mode and Green Book refusals
+31/-6   
Documentation
5 files
use-smile-id-sample-flow-host.test.ts
Update comment on build versus validate verdict                   
+1/-1     
FlowPreflight.swift
Clarify which rules the structural validation covers         
+2/-1     
verify.sh
Correct application ids in Maestro usage comments               
+2/-2     
settings.yaml
Update consent refusal comment for host preflight               
+3/-2     
capture-as-follows-the-document.md
Note that `validate()` now proves job-type refusals           
+3/-8     
Enhancement
2 files
SdkFlowScreen.kt
Misconfigured preflight lands on unsubmitted job details 
+5/-3     
SdkFlowScreen.swift
Misconfigured flow exits to unsubmitted job details           
+4/-2     
Dependencies
10 files
Package.swift
Bump ios-spm pin to new snapshot                                                 
+1/-1     
libs.versions.toml
Bump Android SDK artifacts and njia snapshot builds           
+8/-8     
package.json
Bump Expo SDK packages and njia snapshots                               
+9/-9     
package.json
Bump `@smileid/usesmileid` peer dependency snapshot           
+1/-1     
Package.resolved
Resolve ios-spm, kamera-spm and njia-spm to new snapshots
+6/-6     
Package.resolved
Resolve ios-spm, kamera-spm and njia-spm to new snapshots
+6/-6     
pubspec.yaml
Bump Flutter SDK, ML providers and njia snapshots               
+9/-9     
pubspec.yaml
Bump `usesmileid` to 12.3.1-SNAPSHOT.25                                   
+1/-1     
project.yml
Bump UseSmileID and Njia exact versions                                   
+2/-2     
Package.resolved
Resolve SampleUI dependencies to new snapshots                     
+7/-7     
Configuration changes
1 files
licenses.json
Regenerate licenses with kamera-spm and njia-spm versions
+2/-2     


Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • …and njia 0.0.1-SNAPSHOT.11
    
    The four SDKs repinned to kamera .34 and njia .11 (android#704, ios-v12#606,
    flutter#479, react-native-expo#523) and now ship round 4's validation change:
    validate() returns the verdict build() reaches. Move every app to those
    snapshots, and let the Android and iOS preflight follow the change: a flow the
    SDK would refuse now lands on the unsubmitted job's details with the reason,
    where the SDK's own Failure lands, instead of returning to the product list.

    Copy link
    Copy Markdown
    Member

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Approved: 📌 apps: every app runs the SDK snapshots built on kamera 1.2.1-SNAPSHOT.34 and njia 0.0.1-SNAPSHOT.11

    Changes 22 files: android/app/src/main/kotlin/com/usesmileid/sampleapps/android/flow/SdkFlowScreen.kt, android/app/src/test/kotlin/com/usesmileid/sampleapps/android/SdkFlowPreflightTest.kt, android/gradle/libs.versions.toml, android/maestro/settings.yaml, android/verify.sh, and 17 more.

    Checks at 1d927ed: 1 of 18 passed, 17 still running.

    @jumaallan
    Juma Allan (jumaallan) merged commit 43d00d0 into main Oct 26, 2026
    19 of 20 checks passed
    @jumaallan
    Juma Allan (jumaallan) deleted the chore/repin-v12-njia-11 branch October 26, 2026 03:08
    @prfectionist

    prfectionist Bot commented Oct 26, 2026

    Copy link
    Copy Markdown

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 3 🔵🔵🔵⚪⚪
    🏅 Score: 82
    🧪 PR contains tests
    🔒 No security concerns identified
    🔀 Multiple PR themes

    Sub-PR theme: Repin all four apps to the new SDK, kamera and njia snapshots

    Relevant files:

    • android/gradle/libs.versions.toml
    • ios/SampleUI/Package.swift
    • ios/App/project.yml
    • ios/SampleUI/Package.resolved
    • ios/SampleUI/Sources/SampleUI/Resources/licenses.json
    • flutter/app/pubspec.yaml
    • flutter/sample_ui/pubspec.yaml
    • flutter/app/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
    • flutter/app/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved
    • expo/app/package.json
    • expo/sample-ui/package.json

    Sub-PR theme: Update the documented Maestro app id

    Relevant files:

    • android/verify.sh

    ⚡ Recommended focus areas for review

    Preflight gap on iOS

    The new comment says validator.validate(configuration:) runs only screen and structural rules, and that the job rules run in the SDK's build(). If so, the iOS preflight still misses job-type refusals such as the Green Book on Enhanced Document Verification.

    That contradicts the PR description and the updated plan doc, which say validate() sees these "on every platform". Android now has a test for the Green Book refusal and the agent-mode/enhanced-liveness pair, but nothing in the diff shows iOS asserting either case.

    Two outcomes follow:

    • If iOS misses them, the run goes past preflight to the SDK's own Failure instead of the new .misconfigured landing.
    • Either way, the docs or the comment are wrong.

    Add an iOS preflight test for both refusals, or correct the doc and the description.

    // The screen and structural rules, which need no network or ML block; the SDK's build also runs the
    // job rules. Warnings do not block a run.
    let structural = validator
      .validate(configuration: useSmileIDSampleConfiguration(snapshot, params: params))
      .errors
    return structural.isEmpty ? .ready : .misconfigured(issues: structural.map(\.useSmileIDSampleReason))
    Untested navigation change

    A Misconfigured preflight now lands on VerificationDetails with UNSUBMITTED_JOB_ID instead of returning to the product list. iOS makes the same change in SdkFlowScreen.swift.

    This is a behaviour change, and no test in the diff covers it on either platform. The repo's test-first rule requires one. Without it, a regression back to the product list, or a landing that shows an empty details screen, goes unnoticed.

    The Maestro consent flow comment was updated, but the diff does not show that the flow's assertions follow the new landing.

    is FlowPreflight.Misconfigured -> {
        val issues = preflight.issues
        LaunchedEffect(Unit) {
            app.flowResult.recordBlocked(
                issues.joinToString("; ") { it.message ?: it::class.simpleName.orEmpty() }
                    .ifBlank { "The flow did not validate" },
                snapshot.environment,
            )
            engine.leaveRun(scope.entry, UseSmileIDSampleStep.VerificationDetails.wireName, arg = UNSUBMITTED_JOB_ID)
        }
        return
    }
    Unrelated app id change

    The documented Maestro APP_ID moves from com.usesmileid.sampleapps.android(.debug) to com.usesmileid.sample.android(.debug). This is unrelated to the snapshot repin.

    If the shell's actual applicationId is still the old value, anyone running these commands targets an app that is not installed. If the new id is the correct one, it should match spec/app-identity.json.

    Unverified from the diff: confirm against spec/app-identity.json and the Gradle applicationId.

    #   maestro --device <serial> test -e APP_ID=com.usesmileid.sample.android.debug android/maestro
    #   maestro --device <serial> test -e APP_ID=com.usesmileid.sample.android       android/maestro

    Comment on lines +231 to +233
    document products. The builder's `validate()` proves it on every platform: it returns the verdict
    `build()` reaches, job-type rules included, so `SdkFlowPreflightTest` sees the Green Book refusal on
    Enhanced Document Verification.

    Copy link
    Copy Markdown

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: The doc now says validate() proves job-type rules on every platform. The iOS preflight in this same PR says the opposite: its validator.validate(configuration:) runs only screen and structural rules, and "the SDK's build also runs the job rules". So on iOS the Green Book refusal still escapes preflight. Scope the claim to the platforms where it holds and keep the iOS gap visible, ideally as a backlog item. [general, importance: 5]

    Suggested change
    document products. The builder's `validate()` proves it on every platform: it returns the verdict
    `build()` reaches, job-type rules included, so `SdkFlowPreflightTest` sees the Green Book refusal on
    Enhanced Document Verification.
    document products. On Android, Flutter and React Native the builder's `validate()` proves it: it
    returns the verdict `build()` reaches, job-type rules included, so `SdkFlowPreflightTest` sees the
    Green Book refusal on Enhanced Document Verification. On iOS the preflight's
    `FlowValidator.validate(configuration:)` runs only the screen and structural rules, so job-type
    refusals still surface only from the SDK's build.

    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

    Projects

    None yet

    Development

    Successfully merging this pull request may close these issues.

    2 participants