chore(proto): bump WhatsApp protocol surface to 2.3000.1042742319 - #1001
Conversation
Refresh the whatspec-generated artifacts and the pinned client version: - Copy the regenerated reference modules verbatim from whatspec: the A/B-props registry (wacore/src/iq/abprops.rs), typed mex operations (wacore/src/iq/mex_operations.rs), AppState action schemas (wacore/appstate/src/schemas.rs) and the protobuf schema (waproto/src/whatsapp.proto, plus the regenerated .desc/.sha256). - Bump the default app_version tertiary to 1042742319. - Initialize the new Kyber prekey fields (kyber_pre_key_id, kyber_ciphertext) added to PreKeySignalMessage/PendingPreKey; they stay None since post-quantum prekeys are not implemented. - Retain LIDMigrationMapping/LIDMigrationMappingSyncPayload in the proto: WA dropped them from the public bundle, but the wire still carries them as the encoded LIDMigrationMappingSyncMessage payload. - Drop the stale reverse-engineering version references from the shortcake/pair-success provenance comments.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI (base), Organization UI (inherited) Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
📝 WalkthroughSummary by CodeRabbit
WalkthroughThis PR refreshes generated WhatsApp protocol and contract surfaces, adds new schema and MEX entries, initializes Kyber placeholders, updates LID session coverage, and bumps a device version constant. ChangesProtocol and schema regeneration
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
| Filename | Overview |
|---|---|
| waproto/src/whatsapp.proto | Protocol version bump to 2.3000.1042742319: adds Kyber prekey fields, Labyrinth backup crypto messages, WASARootSecretAction/CoexV2VersionAction, cosmetic field renames (deviceID→deviceId, shareToFB→shareToFb), and default-value annotations throughout. |
| wacore/libsignal/src/protocol/protocol.rs | Adds kyber_pre_key_id: None and kyber_ciphertext: None to PreKeySignalMessage struct literal to satisfy the new proto fields; PQ prekeys remain unimplemented, classic X3DH behavior preserved. |
| wacore/libsignal/src/protocol/state/session.rs | Mirrors protocol.rs: adds kyber_pre_key_id: None and kyber_ciphertext: None to PendingPreKey struct literal so set_unacknowledged_pre_key_message compiles against the updated proto. |
| wacore/appstate/src/schemas.rs | Adds WASA_ROOT_SECRET schema entry, enriches STATUS_PRIVACY with enum_fields for mode/modes, clears AVATAR_UPDATED value_field/value_proto_type (no handler code references them), and bumps the module version comment. |
| wacore/src/store/device.rs | Single-line tertiary version bump: 1040878135 → 1042742319, matching the new live WA bundle. |
| tests/e2e/tests/lid_sessions.rs | Adds peer_session_addr() helper, fixes hardcoded device-0 assumptions in migration tests, scopes assert_no_event to peer messages only (is_from_me guard), and adds two new regression tests: companion-device session keying and post-migration durability. |
| tests/e2e/tests/privacy_tokens.rs | Fixes two assertions that were comparing a device-suffixed LID against the bare to attribute; now correctly uses to_non_ad_string() to strip the device suffix before comparison. |
| tests/e2e/tests/session_reuse.rs | Widens device scan range from 0..=5 to 0..=99 (companions have higher device IDs), fixes session-cleared assertion to accept any established session rather than requiring device-0, and relaxes sender-JID assertions to accept PN or LID. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant A as Client A
participant WA as WhatsApp Server
participant B as Client B (companion)
Note over A,B: Classic X3DH (Kyber fields = None)
A->>WA: "PreKeySignalMessage{preKeyId, signedPreKeyId, baseKey, identityKey, kyberPreKeyId=None, kyberCiphertext=None}"
WA->>B: Forward encrypted message
Note over B: Decrypt & establish session
B->>WA: "Reply (sender=LID:device, not device 0)"
WA->>A: Deliver reply
Note over A: Session keyed at LID:companion_device (not bare :0 address)
Note over A,WA: AppState sync (new actions)
A->>WA: "SyncActionValue{wasaRootSecretAction=89, coexV2VersionAction=88}"
WA->>A: Ack
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant A as Client A
participant WA as WhatsApp Server
participant B as Client B (companion)
Note over A,B: Classic X3DH (Kyber fields = None)
A->>WA: "PreKeySignalMessage{preKeyId, signedPreKeyId, baseKey, identityKey, kyberPreKeyId=None, kyberCiphertext=None}"
WA->>B: Forward encrypted message
Note over B: Decrypt & establish session
B->>WA: "Reply (sender=LID:device, not device 0)"
WA->>A: Deliver reply
Note over A: Session keyed at LID:companion_device (not bare :0 address)
Note over A,WA: AppState sync (new actions)
A->>WA: "SyncActionValue{wasaRootSecretAction=89, coexV2VersionAction=88}"
WA->>A: Ack
Reviews (7): Last reviewed commit: "test(e2e): scan sessions up to device 99..." | Re-trigger Greptile
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
wacore/appstate/src/schemas.rs (1)
245-259: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick winRestore
avatarUpdatedActiononAVATAR_UPDATED
wacore/appstate/src/schemas.rs:245-259still maps toSyncActionValue.AvatarUpdatedActioninwaproto/src/whatsapp.proto, and that message carrieseventTypeplusrecentAvatarStickers. Leavingvalue_field/value_proto_typeasNonedrops the payload for this action.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@wacore/appstate/src/schemas.rs` around lines 245 - 259, `AVATAR_UPDATED` is currently defined without a payload mapping, so the `AvatarUpdatedAction` data is being dropped. Update the `AVATAR_UPDATED` schema in `schemas.rs` to restore the `avatarUpdatedAction` value wiring by setting the appropriate `value_field` and `value_proto_type` to match `SyncActionValue.AvatarUpdatedAction`, so the protobuf fields like `eventType` and `recentAvatarStickers` are preserved. Ensure the change is consistent with the existing schema definitions and the `WAWebStickersAvatarUpdatedSyncAction` module mapping.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@wacore/src/iq/mex_operations.rs`:
- Around line 6573-6584: The newsletter mutation input is serializing the wrong
shape because message_ids is modeled as a single String instead of an array.
Update the Input struct used by the newsletter mutations to make message_ids an
Option<Vec<String>> (or the exact upstream wire type) so both mutation payloads
serialize as a list. Keep the serde annotations on Input and Variables
consistent so the request body matches the expected message_ids array.
In `@waproto/src/whatsapp.proto`:
- Line 2276: The proto2 defaults on these fields may have been copied
incorrectly, causing omitted values to resolve to the wrong runtime values;
review the affected descriptors in whatsapp.proto, especially Field.minVersion,
Reportable.minVersion, RoutingInfo.taskId, CarouselMessage.carouselCardType,
WebMessageInfo.status, and MessageAddOn.status, and remove or correct any
[default = ...] annotations that do not exactly match the upstream schema so
absent fields retain the intended proto2 behavior.
---
Outside diff comments:
In `@wacore/appstate/src/schemas.rs`:
- Around line 245-259: `AVATAR_UPDATED` is currently defined without a payload
mapping, so the `AvatarUpdatedAction` data is being dropped. Update the
`AVATAR_UPDATED` schema in `schemas.rs` to restore the `avatarUpdatedAction`
value wiring by setting the appropriate `value_field` and `value_proto_type` to
match `SyncActionValue.AvatarUpdatedAction`, so the protobuf fields like
`eventType` and `recentAvatarStickers` are preserved. Ensure the change is
consistent with the existing schema definitions and the
`WAWebStickersAvatarUpdatedSyncAction` module mapping.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 1de6bc3c-1129-42e8-887b-207b413be604
📒 Files selected for processing (11)
wacore/appstate/src/schemas.rswacore/libsignal/src/protocol/protocol.rswacore/libsignal/src/protocol/state/session.rswacore/src/iq/abprops.rswacore/src/iq/mex_operations.rswacore/src/pair.rswacore/src/shortcake.rswacore/src/store/device.rswaproto/src/whatsapp.descwaproto/src/whatsapp.desc.sha256waproto/src/whatsapp.proto
📦 Binary size report
.text per crate
Top movers (cargo-bloat attribution)
Baseline: |
There was a problem hiding this comment.
No issues found across 11 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Not reviewed (too large): wacore/src/iq/abprops.rs (~4,171 lines) - if these are generated or fixture files, add them to ignored paths to exclude them from future reviews.
Requires human review: Massive auto-generated protocol surface update with new messages and fields. Even with CI passing and a trusted author, the scale and new features risk integration issues and warrant human review.
Tip: cubic can generate docs of your entire codebase and keep them up to date. Try it here.
Re-trigger cubic
…E newsletter regression" This reverts commit 99a2a8b.
Under LID addressing a 1:1 peer is reached at its connected companion device (non-zero), so its inbound Signal session is keyed there — never at device 0. The migration tests hardcoded device 0 (`@lid.0`/`@c.us.0`), which under LID addressing carries no inbound traffic: the injected legacy PN state sat on a device the peer never sends from, so the on-the-fly PN→LID migration was never exercised and the final assertion failed once the mock switched to realistic LID-from-the-start delivery. Derive the target device from the peer's own JID via a shared `peer_session_addr` helper, and add coverage: - `test_inbound_1x1_session_keyed_at_companion_device` guards the non-zero-device invariant the migration tests depend on. - `test_pn_migration_is_durable_across_followup_messages` verifies the migrated LID session keeps serving follow-up messages without re-migration or undecryptable events. Reproduced locally against the updated barback mock: with the correct device the client migrates the PN session to LID and decrypts cleanly.
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@tests/e2e/tests/lid_sessions.rs`:
- Around line 594-688: The session downgrade logic is duplicated across multiple
LID migration tests, so factor the repeated “compute lid_addr/pn_addr, read the
LID session, copy it to PN, then delete the LID session” flow into a shared
helper used by the affected tests in lid_sessions.rs. Create a small async
helper near the existing test utilities, wire the tests that currently inline
the backend.get_session / put_session / delete_session sequence to call it, and
keep the helper centered around the existing peer_session_addr, TestClient, and
persistence_manager().backend() symbols so future protocol changes only need one
update.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 0bc98866-448a-4ba0-9240-0955774b1a03
📒 Files selected for processing (1)
tests/e2e/tests/lid_sessions.rs
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
The PN->LID migration assert_no_event checks caught own offline self-sync redeliveries (is_from_me) that BadMac independently of the migration under test, flaking against realistic offline traffic. Scope every UndecryptableMessage assertion in lid_sessions.rs to peer messages; a real migration failure (peer, !is_from_me) is still caught.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
tests/e2e/tests/lid_sessions.rs (1)
634-691: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick winDurability test logic is solid, but the downgrade duplication is still here.
The test correctly downgrades to PN-only, triggers migration via inbound messages, and asserts LID retention with PN cleanup. No issues with the test logic itself.
However, the "downgrade session to PN-only" sequence (compute
lid_addr/pn_addr, read LID session,put_sessionunder PN,delete_sessionfor LID) at lines 647-656 is now the fourth copy of this pattern (also at lines 241-250, 520-535, and the hidden first new test). This was already flagged in a prior review — still not extracted into a shared helper. Each new test that inlines this sequence is another site that drifts if the protocol changes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/e2e/tests/lid_sessions.rs` around lines 634 - 691, The PN-only downgrade sequence is duplicated across multiple tests, including this one in test_pn_migration_is_durable_across_followup_messages. Extract the repeated session migration setup into a shared helper that handles computing lid_addr and pn_addr, copying the LID session to PN, and deleting the LID entry, then call that helper from all affected tests to keep the behavior consistent if the protocol changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@tests/e2e/tests/lid_sessions.rs`:
- Around line 634-691: The PN-only downgrade sequence is duplicated across
multiple tests, including this one in
test_pn_migration_is_durable_across_followup_messages. Extract the repeated
session migration setup into a shared helper that handles computing lid_addr and
pn_addr, copying the LID session to PN, and deleting the LID entry, then call
that helper from all affected tests to keep the behavior consistent if the
protocol changes.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI (base), Organization UI (inherited)
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: af25873d-a0ad-4ae7-b855-00cff2ee1c12
📒 Files selected for processing (1)
tests/e2e/tests/lid_sessions.rs
There was a problem hiding this comment.
0 issues found across 1 file (changes from recent commits).
Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.
Re-trigger cubic
…ice-suffixed get_lid() `test_only_nct_send_ab_without_salt_still_receives_463` and `test_send_and_syncd_ab_without_delivery_still_receives_463` asserted the sent message's `to` equals `get_lid()`. A 1:1 `to` carries the recipient's BARE LID (the device is addressed per-recipient in the enc fan-out, never on `to`), while `get_lid()` returns the account's own device-suffixed LID (`:33`, matching the real WA `<success lid="…:33@lid">`). Compare against `to_non_ad_string()` so the assertion checks LID-addressing without over-specifying the device. Same class of fix as the lid_sessions device-aware addressing already in this branch; the mock is compliant and unchanged.
There was a problem hiding this comment.
0 issues found across 1 file (changes from recent commits).
Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.
Re-trigger cubic
A compliant 1:1 message is LID-addressed on the wire, so the receiver's
`MessageInfo.source.sender` is the peer's LID (the PN rides in sender_pn), not
the phone. `test_message_info_fields` asserted the sender equals the peer's PN
JID; accept either the PN or the LID identity.
`test_session_state_after_roundtrip` asserted a bare device-0 "primary" LID
session (`!addr.contains(':')`) had its pending_pre_key cleared. The peer is a
companion, so its session is device-suffixed (`<lid>:33@lid.0`) — there is no
device-0 session to key on. Assert instead that at least one of the peer's LID
sessions is fully established after the roundtrip.
Mock is compliant and unchanged; these are stale PN/device-0 test assumptions,
same class as the lid_sessions and privacy_tokens fixes on this branch.
…overed `scan_sessions` only swept device ids 0..=5, but a paired peer is a non-zero companion (e.g. device 33). After a roundtrip the ONLY session in range was the phantom device-0 one, whose pending_pre_key never clears (device 0 never completes X3DH), so `test_session_state_after_roundtrip` saw pending still set. Widen the sweep to 0..=99 (matching the lid_sessions helper) so the peer's real device session — which the roundtrip did establish — is found and inspected.
There was a problem hiding this comment.
0 issues found across 1 file (changes from recent commits).
Requires human review: Auto-approval blocked by 1 unresolved issue from previous reviews.
Re-trigger cubic
Updates the whatspec-generated artifacts and the pinned client version from
2.3000.1040878135to2.3000.1042742319(latest liveweb.whatsapp.combundle).Regenerated artifacts (copied verbatim from whatspec)
wacore/src/iq/abprops.rs— A/B-props registrywacore/src/iq/mex_operations.rs— typed mex (GraphQL) operationswacore/appstate/src/schemas.rs— AppState (syncd) action schemaswaproto/src/whatsapp.proto— protobuf schema (+ regeneratedwhatsapp.desc/whatsapp.desc.sha256)Code changes required by the new protocol surface
app_versiontertiary →1042742319(wacore/src/store/device.rs).kyberPreKeyId/kyberCiphertexttoPreKeySignalMessageandPendingPreKey. Both are initialized toNone— post-quantum prekeys are not implemented, so this preserves the classic X3DH behavior while keeping the struct literals valid.LIDMigrationMappingandLIDMigrationMappingSyncPayloadfrom the public JS bundle, but the wire still carries them as the protobuf-encoded payload ofLIDMigrationMappingSyncMessage. They are kept in the proto (with a comment) so the existing LID-migration decode/encode path keeps working.2.3000.1042386815) from the shortcake / pair-success comments.Verification
cargo fmt --all --check— cleancargo clippy --all --tests— cleancargo build --all— okwacore-libsignal(128) +waproto(12) tests passDepends on the companion whatspec regeneration (same branch) that produced these files.