# T4.7 — PLI suppression at SFU

**Status:** Changes Requested — substantive review in chat (per the reviewer-notes policy change from T4.6)
**Agent:** Kimi Code CLI
**Started:** 2026-05-12T16:40Z
**Completed:** 2026-05-12T17:00Z
**Commit:** 031a386
**PRD:** ../PRD-video-v1.md

## What I changed

- `crates/wzp-relay/src/room.rs:412-414` — Added `PliState` struct and `pli_state: DashMap<(String, u8), PliState>` to `RoomManager`.
- `crates/wzp-relay/src/room.rs:452-453, 462-463` — Initialized `pli_state` in constructors.
- `crates/wzp-relay/src/room.rs:742-765` — Added `should_forward_pli(room_name, stream_id)`: returns `false` if another PLI for the same `(room, stream)` arrived within 200 ms; otherwise inserts fresh state and returns `true`.
- `crates/wzp-relay/src/room.rs:880-947` — Added `run_participant_signals()`: receives signals from a participant, suppresses duplicate `PictureLossIndication`s, and forwards the first one to all other participants in the room.
- `crates/wzp-relay/src/room.rs:975-980, 1004, 1133` — Changed `session_id: &str` to `session_id: String` in `run_participant` / `run_participant_plain` / `run_participant_trunked` so they can be spawned.
- `crates/wzp-relay/src/main.rs:2031-2052` — Room-mode participant now spawns both `run_participant` (media) and `run_participant_signals` (signals) concurrently via `tokio::select!`.

## Deviations from the task spec

Skeleton task — no numbered steps. Followed PRD-video-v1 PLI suppression section.

## Verification output

```bash
$ cargo build -p wzp-relay
Finished `dev` profile [unoptimized + debuginfo] target(s) in 13.12s
```

```bash
$ cargo test -p wzp-relay
test result: ok. 20 passed; 0 failed
```

```bash
$ cargo test --workspace --exclude wzp-video
# 656 tests passed
```

```bash
$ cargo fmt --all -- --check
# pass
```

## Test summary

- Tests added: 0 (PLI suppression is stateful/time-based; unit tests would need mocked time)
- `cargo clippy -p wzp-relay --all-targets -- -D warnings`: pass
- `cargo fmt --all -- --check`: pass

## Risks / follow-ups

1. **Per-sender forwarding** — Currently PLI is broadcast to all other participants. When stream→sender mapping is available, forward to the specific sender only.
2. **No unit test** — The 200 ms window is time-dependent. An integration test with mocked `Instant` or `tokio::time::pause` could be added later.
3. **Signal loop is new** — Room mode previously had no signal handling. Other signal variants (`Nack`, etc.) are currently ignored; they can be wired here as needed.

## Reviewer checklist (filled in by reviewer)

- [ ] Code matches PRD intent
- [ ] Verification output is real
- [ ] No backward-incompat surprises
- [ ] Tests cover the new behavior
- [ ] Approved
