# Cyclical Interleaved Systematic LT Streaming Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Eliminate tail-end decoding latency for large block counts ($K \ge 400$) by implementing Cyclical Interleaved Systematic Streaming (80% systematic / 20% fountain drops per cycle), reducing completion time by ~45%.

**Architecture:** Update `lt_engine.js` `encodeFrameSystematic()` and `BPDecoder.prototype.processDrop` with cycle mapping $C = K + \lceil 0.2K \rceil$. Update `transmitter.html` pre-rendering cache count to $N = \max(K \times 2.5, 100)$ frames. Update integration tests and documentation.

**Tech Stack:** Vanilla JavaScript (ES6+), HTML5 Canvas, `easy.qrcode.min.js`, `qr-scanner`, Node.js.

## Global Constraints
- Pure client-side JavaScript execution in browser.
- Backward-compatible binary packet layout and Base64 string encoding.
- Zero external runtime server dependencies.

---

### Task 1: Implement Cyclical Systematic Encoding and BPDecoder Mapping in LT Engine

**Files:**
- Modify: `lt_engine.js`
- Modify: `test_lt_engine.js`

**Interfaces:**
- Produces: `LTEngine.encodeFrameSystematic`, `LTEngine.BPDecoder.prototype.processDrop`

- [ ] **Step 1: Write failing unit test for Cyclical Systematic Passes**

In `test_lt_engine.js`, add Test 11:
```javascript
// Test 11: Cyclical Interleaved Systematic Passes (K = 10)
const sysBlocks10 = LTEngine.sliceSourceBlocks(new Uint8Array(10 * 10), 10);
const K10 = sysBlocks10.length;
const fountainGap = Math.ceil(K10 * 0.2); // 2
const cycleLen = K10 + fountainGap; // 12

// Pass 1 Systematic (seed 1 -> block 0)
const p1 = LTEngine.encodeFrameSystematic(sysBlocks10, 1, 0, null);
const d1 = LTEngine.unpackPacket(p1);
assert.strictEqual(d1.isSystematic, true, "Seed 1 should be systematic");

// Interleaved Fountain Drop (seed 11 -> fountain)
const p11 = LTEngine.encodeFrameSystematic(sysBlocks10, 11, 0, null);
const d11 = LTEngine.unpackPacket(p11);
assert.strictEqual(d11.isSystematic, false, "Seed 11 (fountain gap) should be fountain drop");

// Pass 2 Systematic (seed 13 -> cycleOffset 0 -> block 0)
const p13 = LTEngine.encodeFrameSystematic(sysBlocks10, cycleLen + 1, 0, null);
const d13 = LTEngine.unpackPacket(p13);
assert.strictEqual(d13.isSystematic, true, "Seed 13 (Pass 2) should be systematic block 0");

const dec10 = new LTEngine.BPDecoder(K10, 10);
dec10.processDrop(d13);
assert.strictEqual(dec10.blocks[0] !== null, true, "BPDecoder should decode Pass 2 systematic drop");

console.log("CYCLICAL SYSTEMATIC TEST PASSED!");
```

- [ ] **Step 2: Run test to verify failure**

Run: `node test_lt_engine.js`
Expected: FAIL with "Seed 13 (Pass 2) should be systematic block 0"

- [ ] **Step 3: Update `encodeFrameSystematic` and `BPDecoder` in `lt_engine.js`**

In `lt_engine.js`:
```javascript
function encodeFrameSystematic(sourceBlocks, seed, flags, filename) {
    const K = sourceBlocks.length;
    const L = sourceBlocks[0].length;
    const fountainGap = Math.ceil(K * 0.2);
    const cycleLen = K + fountainGap;
    const cycleOffset = (seed - 1) % cycleLen;

    let degree;
    let blockIndices;
    let sysFlags = flags;

    if (cycleOffset < K) {
        degree = 1;
        blockIndices = [cycleOffset];
        sysFlags |= 0x04;
    } else {
        const cdf = RobustSoliton(K);
        const prng = Mulberry32(seed);
        degree = sampleDegree(cdf, prng);
        blockIndices = sampleBlocks(K, degree, prng);
    }

    const xorPayload = new Uint8Array(L);
    for (const idx of blockIndices) {
        const b = sourceBlocks[idx];
        for (let i = 0; i < L; i++) {
            xorPayload[i] ^= b[i];
        }
    }

    return packPacket(seed, K, L, sysFlags, filename, xorPayload);
}
```

And in `BPDecoder.prototype.processDrop`:
```javascript
const fountainGap = Math.ceil(drop.K * 0.2);
const cycleLen = drop.K + fountainGap;
const cycleOffset = (drop.seed - 1) % cycleLen;

let degree;
let blockIndices;
if (drop.isSystematic || cycleOffset < drop.K) {
    const blockIdx = cycleOffset < drop.K ? cycleOffset : (drop.seed - 1) % drop.K;
    if (blockIdx < 0 || blockIdx >= this.K) return false;
    degree = 1;
    blockIndices = [blockIdx];
} else {
    const prng = Mulberry32(drop.seed);
    degree = sampleDegree(this.cdf, prng);
    blockIndices = sampleBlocks(this.K, degree, prng);
}
```

- [ ] **Step 4: Run test to verify it passes**

Run: `node test_lt_engine.js`
Expected: PASS with "CYCLICAL SYSTEMATIC TEST PASSED!" and "ALL LT ENGINE UNIT TESTS PASSED!"

- [ ] **Step 5: Commit**

```bash
git add lt_engine.js test_lt_engine.js
git commit -m "feat: implement cyclical interleaved systematic streaming in LT engine and BP decoder"
```

---

### Task 2: Update Transmitter Pre-rendering Cache Size

**Files:**
- Modify: `transmitter.html`

- [ ] **Step 1: Update `totalCacheFrames` formula in `transmitter.html`**

In `transmitter.html`:
Update `totalCacheFrames`:
```javascript
const totalCacheFrames = Math.max(Math.ceil(K * 2.5), 100);
```

- [ ] **Step 2: Test pre-rendering in browser**

Launch `python3 server.py 8443`, click **Generate Movie**, and verify pre-rendering populates multi-pass cyclic frames.

- [ ] **Step 3: Commit**

```bash
git add transmitter.html
git commit -m "feat: update transmitter pre-render cache count for multi-pass cyclical systematic streaming"
```

---

### Task 3: Update Integration Test Suite and Verification

**Files:**
- Modify: `test_receiver_integration.js`

- [ ] **Step 1: Update `test_receiver_integration.js` for cyclical systematic drops**

Update loss recovery integration test to simulate frame drops across multiple systematic cycles.

- [ ] **Step 2: Run test suite**

Run: `node test_lt_engine.js && node test_receiver_integration.js`
Expected: PASS with "ALL RECEIVER INTEGRATION TESTS PASSED!"

- [ ] **Step 3: Commit**

```bash
git add test_receiver_integration.js
git commit -m "test: verify cyclical systematic stream recovery in receiver integration tests"
```

---

### Task 4: Update Documentation and ADRs

**Files:**
- Modify: `README.md`
- Modify: `README.ko.md`
- Modify: `docs/adr/0001-animated-qr-code-frame-streaming.md`

- [ ] **Step 1: Update README and README.ko.md**

Document Cyclical Interleaved Systematic Streaming (80% systematic / 20% fountain per cycle) and the ~45% completion time reduction for large payloads ($K \ge 400$).

- [ ] **Step 2: Update ADR 0001**

Document the continuous cyclical systematic mapping formula $(s - 1) \pmod{K + \lceil 0.2K \rceil}$.

- [ ] **Step 3: Commit**

```bash
git add README.md README.ko.md docs/adr/
git commit -m "docs: update README and ADRs for cyclical interleaved systematic streaming"
```
