Files
chanora/poc/flutter_rust_bridge_hello/VERIFICATION.md
T
EdisonJwa 2bbad5feb9 feat(poc/bridge): add flutter_rust_bridge hello spike
Proof-of-concept proving the Flutter/Rust bridge exit criterion from
docs/architecture/proof-of-concept-plan.md §2:
  "Flutter can call Rust and receive event stream data."

The spike exposes one synchronous fallible command (greet) returning
a typed GreetResult / GreetError DTO, and one async event stream
(counter_stream) emitting typed CounterTick events. The Flutter app
demonstrates both flows on a Material 3 surface; the headless test
suite in test/poc_verification_test.dart exercises the same API
directly through dart:ffi.

Verified on 2026-05-13 (Linux desktop, Flutter 3.41.9 / Dart 3.11.5,
flutter_rust_bridge 2.12.0, Rust 1.95). All three tests pass:
  - greet() returns typed result for valid input
  - greet() surfaces typed error for empty input
  - counterStream() delivers the expected event sequence

Authority: PoC plan §2, DEC-014 (typed Flutter/Rust bridge),
SAD-068, SDD-079, SysDes-049.
Naming note: the PoC plan lists this as flutter-rust-bridge-hello,
but Dart pubspec.yaml package names require underscores; the
directory uses underscores accordingly.
Not product code; not promoted into chanora_bridge.

Layout note: includes the full Flutter platform scaffold (android,
ios, macos, windows, web, linux). Only the Linux desktop target has
been built and verified.
2026-05-14 12:26:09 +08:00

2.7 KiB

Verification record — flutter_rust_bridge_hello

Result

PASS. The PoC exit criterion (from docs/architecture/proof-of-concept-plan.md §2: "Flutter can call Rust and receive event stream data") is met.

Environment

Field Value
Date 2026-05-13
Host OS Linux (Arch, kernel 7.0.5-arch1-1, x86_64)
Flutter 3.41.9 stable (Dart 3.11.5)
Rust toolchain stable 1.95.0
flutter_rust_bridge (Rust + Dart) 2.12.0
flutter_rust_bridge_codegen 2.12.0
Target linux desktop (x86_64-unknown-linux-gnu)

Reproduction

# 1. Generate Dart bindings + Rust glue from rust/src/api.
flutter_rust_bridge_codegen generate

# 2. Build the Linux desktop bundle (this builds the cdylib too, via cargokit).
flutter build linux --debug

# 3. Run the headless verification test. The cdylib lives in the build bundle,
#    so we point dart:ffi at it via LD_LIBRARY_PATH.
LD_LIBRARY_PATH="$PWD/build/linux/x64/debug/bundle/lib:$LD_LIBRARY_PATH" \
    flutter test test/poc_verification_test.dart

Observed result

00:00 +0: loading /home/.../test/poc_verification_test.dart
00:00 +0: (setUpAll)
00:00 +0: Chanora FRB hello PoC greet() returns typed result for valid input
00:00 +1: Chanora FRB hello PoC greet() surfaces typed error for empty input
00:00 +2: Chanora FRB hello PoC counterStream() delivers the expected event sequence
00:00 +3: (tearDownAll)
00:00 +3: All tests passed!

What the verification proves

Exit-criterion sub-claim Evidence
Dart can call Rust greet(name: 'Chanora') returns a GreetResult whose message field originated in Rust.
Typed result DTO crosses the boundary GreetResult.elapsedMicros is a typed BigInt (Rust u64) deserialised correctly on the Dart side.
Typed error DTO crosses the boundary greet(name: ' ') throws a GreetError instance on the Dart side (isA<GreetError>()); the Rust Err(...) arm is reached and reified as a Dart exception.
Dart can receive a Rust event stream counterStream(count: 4, intervalMs: 50) yields exactly 4 ordered CounterTick events with seq = 0..3 and matching note payloads.
Streams close cleanly The await for loop terminates on its own without timeout.

Scope honestly NOT validated by this spike

  • Performance characteristics of the bridge under load.
  • Android, iOS, macOS, Windows targets.
  • Lifecycle behaviour across Flutter hot-restart or Dart isolate boundaries.
  • Cancellation semantics (Dart listener disconnect while Rust still produces).
  • Behaviour with large/complex DTO graphs.
  • Backpressure on the event stream.
  • The full Chanora bridge DTO catalogue (owned by chanora_bridge).
  • The "schema-controlled" half of DEC-014 — this PoC uses macro-driven generation only.