--- tags: [report, wzp] type: report status: Approved --- # T1.1 — Add v2 `MediaHeader` type **Status:** Approved **Agent:** Kimi Code CLI **Started:** 2026-05-11T06:09Z **Completed:** 2026-05-11T06:54Z **Commit:** see git log **PRD:** ../PRD-wire-format-v2.md ## What I changed - `crates/wzp-proto/src/packet.rs:20` — renamed existing `MediaHeader` → `MediaHeaderV1` (kept all impls intact) - `crates/wzp-proto/src/packet.rs:157` — added `pub type MediaHeader = MediaHeaderV1;` backward-compat alias so the workspace continues to compile - `crates/wzp-proto/src/packet.rs:160-238` — added new `MediaHeaderV2` struct (16 bytes, byte-aligned) with `write_to`, `read_from`, and flag accessors - `crates/wzp-proto/src/packet.rs:1270-1285` — added `media_header_v2_roundtrip` test - `crates/wzp-proto/src/lib.rs:28` — re-exported `MediaHeaderV1` and `MediaHeaderV2` - `crates/wzp-proto/src/packet.rs:487-493` — added `impl Default for TrunkFrame` (pre-existing clippy fix) - `crates/wzp-proto/src/packet.rs:540` — removed redundant slicing `&buf[..]` → `buf` (pre-existing clippy fix) - `crates/wzp-proto/src/quality.rs:102-109` — derived `Default` for `NetworkContext` with `#[default]` on `Unknown` (pre-existing clippy fix) ## Why these choices Rust does not allow a type alias and a struct with the same name in the same module. The task requires both (a) keeping the old struct accessible as `MediaHeader` so the workspace builds, and (b) adding a new struct also called `MediaHeader`. The pragmatic resolution is to name the new struct `MediaHeaderV2` and export it; T1.5 will delete `MediaHeaderV1`, remove the alias, and rename `MediaHeaderV2` → `MediaHeader` once all call sites are migrated. `CodecId::to_wire` already returns `u8` and was usable immediately. `MediaType` does not exist yet (T1.2), so the `media_type` field is `u8` with a `// TODO(T1.2)` comment. ## Deviations from the task spec 1. **Step 3 (struct name):** The new struct is named `MediaHeaderV2` instead of `MediaHeader`. This is required because `pub type MediaHeader = MediaHeaderV1;` occupies the `MediaHeader` name in `packet.rs`. T1.5 will perform the final rename. 2. **Step 4 (`MediaType` placeholder):** Used `u8` for `media_type` with an inline `// TODO(T1.2)` comment, matching the fallback instruction in the task. 3. **Clippy fixes:** Fixed three pre-existing clippy errors in `wzp-proto` (`new_without_default`, `redundant_slicing`, `derivable_impls`) so the crate passes `-D warnings`. ## Verification output ```bash $ cargo test -p wzp-proto media_header_v2_roundtrip running 1 test test packet::tests::media_header_v2_roundtrip ... ok test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 105 filtered out; finished in 0.00s ``` ```bash $ cargo build -p wzp-proto -p wzp-codec -p wzp-fec -p wzp-crypto -p wzp-transport -p wzp-relay -p wzp-client -p wzp-web -p wzp-native Compiling wzp-proto v0.1.0 ... Finished `dev` profile [unoptimized + debuginfo] target(s) in 27.24s ``` ```bash $ cargo test -p wzp-proto -p wzp-codec -p wzp-fec -p wzp-crypto -p wzp-transport -p wzp-relay -p wzp-client -p wzp-web -p wzp-native --no-fail-fast ... test result: ok. 565 passed; 0 failed; ... ``` ```bash $ cargo clippy -p wzp-proto --all-targets -- -D warnings Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.38s ``` ```bash $ cargo fmt --all -- --check # (clean) ``` ## Test summary - Tests added: 1 (`media_header_v2_roundtrip`) - Tests modified: 0 - Workspace test count before: 564 pass / 0 fail (non-Android subset) - Workspace test count after: 565 pass / 0 fail (non-Android subset) - `cargo clippy --workspace --all-targets -- -D warnings`: pass for `wzp-proto`; 3 pre-existing failures remain in `deps/featherchat/warzone/crates/warzone-protocol` (git submodule, outside our control) - `cargo fmt --all -- --check`: pass ## Risks / follow-ups - Pre-existing clippy errors in the `featherchat` git submodule (`warzone-protocol`) remain unresolved because they are in a dependency subtree. - `wzp-android` cannot be built or tested on macOS without the Android NDK. All verification uses the non-Android workspace subset. - `MediaHeaderV2` must be renamed to `MediaHeader` in T1.5 after `MediaHeaderV1` is deleted and all call sites are migrated. - `media_type: u8` should become `media_type: MediaType` once T1.2 lands. ## Reviewer checklist (filled in by reviewer) - [x] Code matches PRD intent - [x] Verification output is real (re-run if suspicious) — re-ran `cargo test -p wzp-proto media_header_v2_roundtrip` (1 passed), `cargo clippy -p wzp-proto --all-targets -- -D warnings` (clean), `cargo fmt --all -- --check` (clean). - [x] No backward-incompat surprises — `pub type MediaHeader = MediaHeaderV1` alias keeps all current call sites compiling, as the task intended. - [x] Tests cover the new behavior - [x] Approved ### Reviewer notes (2026-05-11) Approved. Two minor follow-ups spawned as standalone tasks: 1. **T1.1.1 — Add rustdoc on `MediaHeaderV2` public fields.** Match the `///` doc-comment pattern used by the pre-existing `MediaHeaderV1`. Coding standard #9. 2. **T1.1.2 — Refresh stale test-count figures in docs.** The "272 tests" figure in `ARCHITECTURE.md` and the TASKS environment-setup block is from an older snapshot; the actual non-Android baseline is 564 (with T1.1's new test, 565). Agent reported the right number; the docs are wrong. Both are non-blocking. T1.2 is claimable independently. ### Policy clarifications surfaced by this task - **Pre-existing clippy/fmt fixes are acceptable scope creep** when you are forced to fix them to get a clean `-D warnings` run on the crate you're touching. T1.1 fixed three of these (`TrunkFrame::Default`, `redundant_slicing`, `NetworkContext::Default` derive); all three were disclosed under "Deviations". Continue this pattern — disclose, don't hide. - **Naming workaround acceptable.** `MediaHeaderV2` instead of `MediaHeader` is the right call given Rust's type-vs-struct name collision. T1.5 will resolve.