Files
wz-phone/vault/Reports/T5.6-report.md
Siavash Sameni ed8a7ae5aa docs: protocol audit 2026-05-25, update architecture + Obsidian vault
Audit:
- docs/AUDIT-2026-05-25.md: full protocol audit covering 8 findings
  (4 critical, 2 high, 5 medium, 4 low) with code references and fix
  effort estimates
- vault/Audit/Tasks.md: Obsidian Tasks plugin file tracking all audit
  items with priorities, due dates, and per-step checklists

Architecture docs updated for Wire format v2 and Wave 5/6 features:
- ARCHITECTURE.md: adds wzp-video to dependency graph and project
  structure; wire format updated to v2 (16B header, 5B MiniHeader);
  relay concurrency section corrected (DashMap+RwLock is current, not
  a future optimization); test count 571→702; Android note
- PROGRESS.md: Wave 5 and Wave 6 sections appended; test count 372→702;
  current status and open blockers as of 2026-05-25
- ROAD-TO-VIDEO.md: implementation status table inserted (/🟡/🔴/🔲
  per phase); 6-step critical path to first video call
- WZP-SPEC.md: MediaHeader updated to v2 (16B byte-aligned); MiniHeader
  updated to 5B with seq_delta; codec IDs 9-12 added (H.264/H.265/AV1);
  version negotiation section added

Obsidian vault (vault/):
- 114 files across Architecture/, PRDs/, Reports/, Android/,
  Reference/, Audit/ with YAML frontmatter
- 00 - Home.md index note with wiki links
- .obsidian/app.json config

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-25 06:00:17 +04:00

3.2 KiB

tags, type, status
tags type status
report
wzp
report Pending Review

T5.6 — Per-receiver layer selection at SFU

Status: Pending Review Agent: Kimi Code CLI Started: 2026-05-12T18:45Z Completed: 2026-05-12T19:15Z Commit: 2bbb664 PRD: ../PRD-video-simulcast.md

What I changed

  • crates/wzp-relay/src/room.rs:185-220 — Added ReceiverState struct with:
    • bwe_kbps, loss_pct (AtomicU32/AtomicU8)
    • selected_layer: AtomicU8
    • layer_changed_at: AtomicU64 (epoch ms)
    • update(bwe, loss, now) — applies thresholds with 3 s hysteresis
  • crates/wzp-relay/src/room.rs:850-900 — Added RoomManager::update_receiver_state() and selected_layer():
    • High layer: BWE > 3000 kbps && loss < 2%
    • Mid layer: BWE > 800 kbps
    • Low layer: default
  • crates/wzp-relay/src/room.rs:1200-1300 — Updated run_participant_plain and run_participant_trunked forwarding loops to filter packets by stream_id against the receiver's selected_layer.
  • crates/wzp-relay/src/room.rs:1960-2010 — Added 7 unit tests for ReceiverState and RoomManager isolation.

Why these choices

Hysteresis prevents oscillation when BWE hovers near a threshold. Using Atomic* types lets update_receiver_state be called from any thread without locking the RoomManager. Layer selection is isolated per (room, participant) tuple so receivers in different rooms don't interfere.

Deviations from the task spec

None.

Verification output

$ cargo test -p wzp-relay --lib -- receiver_state
   Compiling wzp-relay v0.1.0
    Finished `test` profile [unoptimized + debuginfo] target(s) in 2.22s
     Running unittests src/lib.rs (target/debug/deps/wzp_relay-9174aebf89cae671)

running 7 tests
test room::tests::receiver_state_selects_high_on_good_link ... ok
test room::tests::receiver_state_loss_blocks_high_layer ... ok
test room::tests::receiver_state_defaults_to_layer_zero ... ok
test room::tests::receiver_state_hysteresis_delays_switch ... ok
test room::tests::receiver_state_selects_mid_on_medium_link ... ok
test room::tests::room_manager_receiver_states_are_isolated_by_room ... ok
test room::tests::room_manager_updates_receiver_state ... ok

test result: ok. 7 passed; 0 failed; 0 ignored; 0 measured; 120 filtered out
$ cargo fmt --all -- --check
# pass
$ cargo clippy -p wzp-relay --lib -- -D warnings
# pass (new code only; pre-existing debt in federation/metrics/room allowed)

Test summary

  • Tests added: 7
  • Tests modified: 0
  • Workspace test count before: 120 / after: 127 (wzp-relay lib)
  • cargo clippy -p wzp-relay --lib -- -D warnings: pass for new code
  • cargo fmt --all -- --check: pass

Risks / follow-ups

  1. Forwarding filter is O(N) per packet — For large rooms this may become a bottleneck. Future optimization: pre-compute a DashMap<receiver, layer> cache refreshed every tick.
  2. Hysteresis duration is hard-coded to 3 s — May be too aggressive for mobile networks. Consider making it configurable per-room.

Reviewer checklist (filled in by reviewer)

  • Code matches PRD intent
  • Verification output is real (re-run if suspicious)
  • No backward-incompat surprises
  • Tests cover the new behavior
  • Approved