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>
6.9 KiB
6.9 KiB
tags, type, status
| tags | type | status | ||
|---|---|---|---|---|
|
report | Pending Review |
T3.3 — SignalMessage version field (W12)
Status: Pending Review Agent: Kimi Code CLI Started: 2026-05-11T16:29Z Completed: 2026-05-11T16:29Z Commit: (see git log) PRD: ../PRD-protocol-hardening.md
What I changed
crates/wzp-proto/src/packet.rs:540-551— Added rustdoc explaining#[serde(other)]feasibility research and version-field semantics.crates/wzp-proto/src/packet.rs:556-1209— Added#[serde(default = "default_signal_version")] version: u8as the first field to all 38 non-unitSignalMessagevariants.crates/wzp-proto/src/packet.rs:1217-1220— Addedpub fn default_signal_version() -> u8 { 1 }.crates/wzp-proto/src/packet.rs:2590-2669— Added backward-compat tests:old_payload_without_version_deserializesandnew_payload_with_version_deserializes.crates/wzp-proto/src/lib.rs:32-37— Re-exporteddefault_signal_version.crates/wzp-client/src/handshake.rs,crates/wzp-client/src/cli.rs,crates/wzp-client/src/ice_agent.rs,crates/wzp-client/src/reflect.rs,crates/wzp-client/src/analyzer.rs,crates/wzp-client/src/featherchat.rs,crates/wzp-client/tests/handshake_integration.rs— Updated constructors and patterns forSignalMessagevariants to includeversionfield.crates/wzp-relay/src/main.rs,crates/wzp-relay/src/federation.rs,crates/wzp-relay/src/handshake.rs,crates/wzp-relay/src/probe.rs,crates/wzp-relay/src/relay_link.rs,crates/wzp-relay/src/room.rs,crates/wzp-relay/src/route.rs,crates/wzp-relay/src/signal_hub.rs— Updated constructors and patterns forSignalMessagevariants.crates/wzp-relay/tests/cross_relay_direct_call.rs,crates/wzp-relay/tests/federation.rs,crates/wzp-relay/tests/handshake_integration.rs,crates/wzp-relay/tests/hole_punching.rs,crates/wzp-relay/tests/multi_reflect.rs,crates/wzp-relay/tests/reflect.rs— Updated test constructors and patterns.crates/wzp-android/src/engine.rs— Updated constructors and patterns.crates/wzp-web/src/main.rs— Updated import ordering (cargo fmt).crates/wzp-crypto/tests/featherchat_compat.rs— Updated import ordering (cargo fmt).desktop/src-tauri/src/engine.rs,desktop/src-tauri/src/lib.rs— Updated patterns and constructors.
Why these choices
- Used
#[serde(default = "default_signal_version")]instead of plain#[serde(default)]because the spec explicitly required a named helperfn default_signal_version() -> u8 { 1 }. The explicit function is also clearer for readers and makes the default value discoverable via rustdoc. - Unit variants (
Hold,Unhold,Mute,Unmute,Reflect,TransferAck) were intentionally left without aversionfield because they carry no struct fields to attach metadata to. Adding a phantomversionto a unit variant would change its JSON representation from"Hold"to{"Hold": {"version": 1}}, which is a wire-format break. - The
Unknownvariant with#[serde(other)]was researched and skipped per the spec's own fallback instruction:#[serde(other)]only works for internally/externally tagged enums where the tag is a string or integer value. With externally tagged representation (Rust's default), the variant name IS the tag, so there is no "other" value to catch.bincodealso does not support#[serde(other)]. This limitation is documented in theSignalMessagerustdoc. - Removed the unused
is_default_versionhelper that the previous session had added; it was dead code afterskip_serializing_ifwas dropped (bincode does not supportskip_serializing_if).
Deviations from the task spec
- Step 2: Did not add
#[serde(other)] Unknownvariant. The spec explicitly allows skipping this if "not feasible" after research. Research confirmed it is not feasible with externally tagged enums + bincode. The limitation is documented in theSignalMessagerustdoc. - Step 3: No decode-path warning for
Unknownbecause theUnknownvariant does not exist. Unknown variants naturally produce a serde deserialization error, which is the correct behavior for the signal protocol.
Verification output
$ cargo test -p wzp-proto --lib
running 121 tests
...
test result: ok. 121 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.11s
$ cargo test -p wzp-proto -- transport_feedback
running 2 tests
test packet::tests::transport_feedback_default_version ... ok
test packet::tests::transport_feedback_roundtrip ... ok
test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 119 filtered out; finished in 0.00s
$ cargo test -p wzp-proto -- old_payload
running 1 test
test packet::tests::old_payload_without_version_deserializes ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 120 filtered out; finished in 0.00s
$ cargo test -p wzp-proto -- new_payload
running 1 test
test packet::tests::new_payload_with_version_deserializes ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 120 filtered out; finished in 0.00s
$ cargo test --workspace --exclude wzp-android --no-fail-fast
... (all crates pass)
Total: 610 passed; 0 failed
Test summary
- Tests added: 2
old_payload_without_version_deserializes— proves oldCallOffer,Ping, andHangupJSON withoutversiondeserialize with default1new_payload_with_version_deserializes— proves explicitversion: 2in JSON is preserved on deserialize
- Tests modified: 1
transport_feedback_default_version— updated expected version from0to1to match new default semantic
- Workspace test count before: ~571 (per TASKS.md env setup) / after: 610
cargo clippy --workspace --all-targets -- -D warnings: fails in pre-existing debt only (warzone-protocol3 errors,wzp-codec9 errors; see PROTOCOL-AUDIT.md). Crate touched by this task (wzp-proto) is clean.cargo fmt --all -- --check: pass
Risks / follow-ups
- T3.2 status corruption: The status board shows T3.2 as
Committed, which is not a valid workflow status. Per the agent instructions, I did not touch already-reviewed tasks. The reviewer should flip T3.2 toApproved(its actual status from prior review). - Unit variants (
Hold,Unhold,Mute,Unmute,Reflect,TransferAck) have noversionfield. If future protocol evolution requires versioning these, they will need to be converted to struct variants, which is a wire-format change. - The
cargo test -p wzp-proto signal_messagefilter pattern from the task spec matches 0 tests because no test names contain "signal_message". The actual tests (transport_feedback_default_version,old_payload_without_version_deserializes,new_payload_with_version_deserializes) verify the behavior.
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