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.
69 lines
2.7 KiB
Markdown
69 lines
2.7 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
# 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.
|