# ADR 0004: Real-time Out-of-Order Frame Assembly & Progress Tracking

* **Status**: Accepted (Updated)
* **Date**: 2026-08-07
* **Deciders**: Core Development Team

---

## Context

Because optical QR frame streaming plays in a continuous loop over an air gap, the receiving camera may begin scanning at any arbitrary moment. Furthermore, camera frames may be dropped due to motion blur, screen glare, or temporary physical obstruction.

Requiring fixed sequential frame capture (frames $1 \to 2 \to 3 \to \dots \to N$) leads to severe optical transmission stalls whenever a single frame is skipped.

---

## Decision

We decided to implement an **asynchronous out-of-order Belief Propagation (BP) graph decoder** on the receiver:

1. **Rateless Droplet Processing**: Each scanned QR frame contains a binary packet carrying a random PRNG seed `s` and a raw XOR payload. The receiver unpacks the drop and computes block indices via Mulberry32 PRNG and Robust Soliton degree distributions.
2. **Belief Propagation Bipartite Graph**: The decoder maintains an array of resolved source blocks `blocks[0..K-1]` and a bipartite graph of unsolved drop nodes.
3. **Cascading Resolution**:
   - When a degree-1 drop arrives (or is reduced to degree 1 by substituting known blocks), its source block is immediately resolved.
   - The resolved block's byte vector is substituted (XORed) into all other graph nodes containing that block, reducing their degree and recursively triggering cascading block resolutions.
4. **Dynamic Progress Grid**: Upon receiving the first valid packet header (which declares total blocks $K$), the UI dynamically initializes a visual grid of $K$ cells representing all source blocks.
5. **Real-Time Visual Feedback**: Each grid cell highlights blue (`.received`) instantly as its corresponding source block index is solved by the BP graph decoder.
6. **Completion Trigger**: Once all $K$ source blocks are resolved (`solvedCount === K`), the receiver automatically stops camera scanning, concatenates the resolved block byte arrays into a contiguous `Uint8Array`, decodes UTF-8 text or triggers an automatic browser file download, and resets device resources.

---

## Consequences

### Positive
* **Robust Transmission**: The receiver can start scanning at any point during playback and tolerates dropped or skipped frames cleanly without transmission stalls.
* **Instant Visual Feedback**: The interactive grid visually informs the user in real time how many blocks are solved out of $K$.
* **Linear Time Decoding**: Belief Propagation graph peeling runs in $O(K \ln K)$ linear time in client-side JavaScript, ensuring smooth decoding performance on mobile browser streams.

### Negative
* **Memory Footprint**: Graph nodes and solved source blocks reside in browser memory until reassembly completes (suitable for files up to tens of megabytes).
