Skip to content

feat(send): add targeted retransmission controls - #1071

Merged
jlucaso1 merged 10 commits into
mainfrom
agent/targeted-retransmission-controls
Jul 22, 2026
Merged

feat(send): add targeted retransmission controls#1071
jlucaso1 merged 10 commits into
mainfrom
agent/targeted-retransmission-controls

Conversation

@jlucaso1

Copy link
Copy Markdown
Collaborator

Summary

  • add a public, typed Client::retransmit_message operation for targeted direct, group, status, and broadcast-list retransmissions
  • share the canonical pairwise retry encoder and the existing session, sender-key, persistence, and transport paths with automatic retry handling
  • rebuild status retries immediately for only the requesting device, including sender-key distribution when required
  • add a reusable Freshness policy for group metadata and device resolution without clear-then-fetch cache windows
  • allow optional status message IDs and neutral extra stanza children while rejecting send-owned structural children before cryptographic state changes
  • replace high-arity send builders with typed request structs and remove intermediate device/sender-key collections

Protocol behavior

The routing and wire policies were checked against the versioned official-client captures for retry jobs, status and broadcast resends, and device/fanout stanza creation.

  • original message IDs and valid retry counts are preserved
  • direct, group, and broadcast retries remain pairwise to the requesting device
  • group retries preserve the group addressing mode; broadcast retries omit it
  • status retries use the sender-key path without fanout to the full audience
  • status retry count remains operation-level state because the captured status wire does not encode it
  • invalid JID classes, route combinations, IDs, counts, and reserved child nodes fail before ratchet advancement

Performance

  • the default cache-preferred path keeps its current I/O behavior
  • refresh publishes successful snapshots without first clearing the current entry
  • message bytes and extra nodes are borrowed by stanza builders where ownership is not required
  • the sender-key forget path no longer builds intermediate reference and cloned-JID vectors
  • device registry results are drained incrementally instead of materializing a second result vector
  • no new dependencies, transport formats, caches, or global locks were introduced

Validation

  • cargo fmt --all -- --check
  • git diff --check
  • cargo check --workspace --all-targets --all-features
  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace --exclude e2e-tests

Environment-dependent E2E tests were not run locally. Binary-size attribution is left to the repository's dedicated CI comparison.

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The PR adds cache freshness controls, restructures message and stanza preparation around typed option/request objects, validates extra stanza nodes and retry routes, and introduces public message retransmission APIs with targeted status retry handling.

Changes

Send and retransmission pipeline

Layer / File(s) Summary
Freshness and device snapshot handling
src/cache.rs, src/client/device_registry.rs, src/features/groups.rs, src/usync.rs, wacore/src/iq/usync.rs
Adds freshness-aware cache and device resolution, complete versus incremental device-list validation, and preservation of warm snapshots after refresh failures.
Send pipeline contracts and dispatch
src/send/mod.rs, src/send/actions.rs, src/client/..., src/features/status.rs, src/message/special.rs, src/pdo.rs
Replaces positional send parameters with structured options, adds freshness fields and stanza-node validation, and routes group, DM, status, peer, edit, and action sends through typed requests.
DM, group, and encryption contracts
wacore/src/send/{dm,group,encrypt}.rs, wacore/src/send/tests.rs, wacore/benches/*
Introduces typed stanza requests, borrowed encoded payloads, SKDM distribution policies, detailed encryption errors, and updated stanza and benchmark coverage.
Validated retransmission routing
src/features/stanza.rs, src/retry.rs
Adds MessageRetransmission, typed retry destinations, route validation, pairwise retry preparation, broadcast-list handling, and requester-only status retransmission.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant SendPipeline
  participant DeviceRegistry
  participant StanzaBuilder
  Client->>SendPipeline: send with freshness and stanza options
  SendPipeline->>DeviceRegistry: resolve or refresh devices
  DeviceRegistry-->>SendPipeline: device snapshot
  SendPipeline->>StanzaBuilder: prepare typed DM or group stanza
  StanzaBuilder-->>Client: prepared message stanza
Loading

Possibly related PRs

Suggested labels: api-design

Suggested reviewers: greptile-apps, cubic-dev-ai

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: adding targeted retransmission controls in send paths.
Description check ✅ Passed The description clearly covers the retransmission, freshness, and send-pipeline changes in the diff.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/targeted-retransmission-controls

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Jul 22, 2026

Copy link
Copy Markdown

📦 Binary size report

Metric main PR Δ
bin size (stripped) 9.68 MiB 9.68 MiB +4.19 KiB (+0.04%) 🔺
bin .text 7.74 MiB 7.74 MiB -2.62 KiB (-0.03%) 🔽
bin allocated (text+data+bss) 9.68 MiB 9.68 MiB +1.70 KiB (+0.02%) 🔺
llvm-lines wacore 492,092 493,286 +1,194 (+0.24%) 🔺
llvm-lines wacore copies 16,249 16,341 +92 (+0.57%) 🔺
llvm-lines whatsapp-rust lib 682,198 688,920 +6,722 (+0.99%) 🔺
llvm-lines whatsapp-rust lib copies 21,846 21,955 +109 (+0.50%) 🔺
deps crates (Cargo.lock) 471 471 0
.text per crate
Crate main PR Δ
.text whatsapp_rust 1.70 MiB 1.67 MiB -21.74 KiB (-1.25%) 🎉
.text wacore 636.61 KiB 638.98 KiB +2.37 KiB (+0.37%) 🔺
.text wacore_binary 89.35 KiB 89.35 KiB 0
.text wacore_libsignal 160.96 KiB 160.96 KiB 0
.text wacore_appstate 22.36 KiB 22.36 KiB 0
.text wacore_noise 22.98 KiB 22.98 KiB 0
.text waproto 1.74 MiB 1.74 MiB 0
.text whatsapp_rust_sqlite_storage 510.58 KiB 510.49 KiB -98 B (-0.02%) 🔽
.text whatsapp_rust_tokio_transport 39.84 KiB 39.84 KiB 0
.text whatsapp_rust_ureq_http_client 10.28 KiB 10.28 KiB 0
.text std 952.34 KiB 968.33 KiB +15.99 KiB (+1.68%) ⚠️
.text other deps 1.88 MiB 1.88 MiB +576 B (+0.03%) 🔺
Top movers (cargo-bloat attribution)
Crate main PR Δ
whatsapp_rust 1.70 MiB 1.67 MiB -21.74 KiB (-1.25%)
std 952.34 KiB 968.33 KiB +15.99 KiB (+1.68%)
wacore 636.61 KiB 638.98 KiB +2.37 KiB (+0.37%)

Baseline: 7ca9c4da2 (latest main run) · Head: c51e07b79 · Graphs

@greptile-apps

greptile-apps Bot commented Jul 22, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds targeted message retransmission controls and reuses the existing send pipeline. The main changes are:

  • Typed retransmission requests for direct, group, status, and broadcast-list messages.
  • Shared session recovery, encryption, persistence, and transport paths.
  • Freshness-aware group metadata and device resolution.
  • Serialized cache publication during metadata and device-registry updates.
  • Typed send options and reduced intermediate allocations.

Confidence Score: 5/5

This looks safe to merge.

  • Sender-key invalidation now uses the resolved encryption identity.
  • Broadcast-list retries now run session recovery before pairwise stanza construction.
  • No blocking issue remains in the reviewed fixes.

Important Files Changed

Filename Overview
src/retry.rs Adds typed retransmission routing, resolved sender-key invalidation, and shared session recovery for pairwise retries.
src/features/groups.rs Adds freshness-aware group metadata loading and serialized metadata publication.
src/client/device_topology.rs Serializes device-registry mutations with authoritative refresh publication.

Reviews (10): Last reviewed commit: "fix(send): validate retry and mapping pu..." | Re-trigger Greptile

Comment thread src/retry.rs Outdated
Comment thread src/retry.rs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 64e448e682

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/retry.rs Outdated
Comment thread src/retry.rs Outdated
Comment thread src/usync.rs Outdated
Comment thread src/retry.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@src/features/groups.rs`:
- Around line 1561-1564: Replace the test phone-like JIDs with reserved
fictitious NANP values matching the 1 + real NPA + 555 + 0100–0199 pattern. In
src/features/groups.rs lines 1561-1564, update the participant JID; in
src/usync.rs lines 400-404, update both the query JID and DeviceListRecord.user
to the same matching compliant value.

In `@src/retry.rs`:
- Around line 3185-3186: Update the fake JIDs in src/retry.rs lines 3185-3186
and 3227 to use NANP fictional numbers with a real NPA, the 555 exchange, and a
0100–0199 line number: replace the direct/requester values with 12025550100 and
12025550100:7, and update the sibling value to 12025550101:9.
🪄 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: 803c9308-ab1e-4ff2-939c-7af12b693264

📥 Commits

Reviewing files that changed from the base of the PR and between aa2582c and 64e448e.

📒 Files selected for processing (21)
  • src/cache.rs
  • src/client/app_state.rs
  • src/client/device_registry.rs
  • src/client/messaging.rs
  • src/client/sender_keys.rs
  • src/features/groups.rs
  • src/features/mod.rs
  • src/features/stanza.rs
  • src/features/status.rs
  • src/lib.rs
  • src/message/special.rs
  • src/pdo.rs
  • src/retry.rs
  • src/send/actions.rs
  • src/send/mod.rs
  • src/sender_key_device_cache.rs
  • src/usync.rs
  • wacore/benches/send_receive_benchmark.rs
  • wacore/src/send/dm.rs
  • wacore/src/send/group.rs
  • wacore/src/send/tests.rs

Comment thread src/features/groups.rs
Comment thread src/retry.rs Outdated
greptile-apps[bot]
greptile-apps Bot previously approved these changes Jul 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@src/retry.rs`:
- Around line 2597-2695: Replace the invalid fictional NANP numbers in the
listed retry tests with valid numbers using a real NPA, the 555 exchange, and
line numbers 0100–0199. Update all occurrences in
update_local_signal_session_cools_resolved_sender_key_namespace,
status_retransmission_resolution_is_cache_aside_with_pn_fallback,
retransmission_route_validation_is_strict_and_typed, and
resolve_retry_chat_info_broadcast_uses_participant_device, preserving each
existing device suffix.
🪄 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: 447c6313-ab42-42fd-a4a7-3086da82bb5f

📥 Commits

Reviewing files that changed from the base of the PR and between 64e448e and 75b40a3.

📒 Files selected for processing (7)
  • src/retry.rs
  • src/send/mod.rs
  • wacore/benches/send_receive_benchmark.rs
  • wacore/src/iq/usync.rs
  • wacore/src/send/encrypt.rs
  • wacore/src/send/group.rs
  • wacore/src/send/tests.rs

Comment thread src/retry.rs
@greptile-apps
greptile-apps Bot dismissed their stale review July 22, 2026 16:00

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

greptile-apps[bot]
greptile-apps Bot previously approved these changes Jul 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/retry.rs (1)

345-350: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Reject self-targeted status retries before mutating sender-key state.

Status routes satisfy uses_sender_key(), so Line 345 marks the requester before retransmit_status_message rejects the sending device at Line 864. The API therefore returns an error after changing sender-key tracking, which can trigger unnecessary redistribution later. Move the shared self-target validation before mark_forget_sender_key; retain the downstream check as defense in depth.

Also applies to: 861-866

🤖 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 `@src/retry.rs` around lines 345 - 350, In the retry flow around
mark_forget_sender_key and retransmit_status_message, perform the shared
self-target validation before mutating sender-key state, so self-targeted status
retries are rejected without marking the requester. Keep the existing downstream
validation near retransmit_status_message as defense in depth.
🤖 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.

Outside diff comments:
In `@src/retry.rs`:
- Around line 345-350: In the retry flow around mark_forget_sender_key and
retransmit_status_message, perform the shared self-target validation before
mutating sender-key state, so self-targeted status retries are rejected without
marking the requester. Keep the existing downstream validation near
retransmit_status_message as defense in depth.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1d543918-5bcf-4c03-a07c-bf144e5adcba

📥 Commits

Reviewing files that changed from the base of the PR and between 75b40a3 and 3769b15.

📒 Files selected for processing (4)
  • src/features/groups.rs
  • src/retry.rs
  • src/usync.rs
  • wacore/src/send/tests.rs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3769b158a4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread wacore/src/iq/usync.rs Outdated
@greptile-apps
greptile-apps Bot dismissed their stale review July 22, 2026 17:24

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@wacore/src/iq/usync.rs`:
- Line 566: Update the require_complete_response field on the public
DeviceListSpec struct to remain public, preserving downstream direct
construction and pattern matching; do not introduce a private field unless the
API is first converted to an explicit constructor or builder flow.
🪄 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: 5734754c-ced5-4f2f-b9f8-d85dfb8ddce3

📥 Commits

Reviewing files that changed from the base of the PR and between 3769b15 and f9afb2b.

📒 Files selected for processing (2)
  • src/usync.rs
  • wacore/src/iq/usync.rs

Comment thread wacore/src/iq/usync.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9afb2bbc5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/usync.rs Outdated
Comment thread src/send/mod.rs
greptile-apps[bot]
greptile-apps Bot previously approved these changes Jul 22, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 `@src/usync.rs`:
- Around line 270-277: Make the refresh path that processes users and invokes
clear_device_record atomic by prevalidating every projected device list,
including the empty-list Freshness::Refresh failure, before any identity cleanup
or registry persistence. Only after all users pass validation should the code
perform cleanup and batched writes; preserve the existing error behavior and
avoid leaving prior device records paired with cleared sessions when validation
fails.
🪄 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: 2979c745-071f-41dc-8ba3-a5dd2181e785

📥 Commits

Reviewing files that changed from the base of the PR and between f9afb2b and e5d749f.

📒 Files selected for processing (8)
  • src/client/device_registry.rs
  • src/send/mod.rs
  • src/usync.rs
  • wacore/src/adv.rs
  • wacore/src/iq/usync.rs
  • wacore/src/send/status.rs
  • wacore/src/send/tests.rs
  • waproto/src/lib.rs

Comment thread src/usync.rs

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e5d749f782

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/usync.rs
Comment thread src/features/groups.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e5d749f782

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/usync.rs
Comment thread src/features/groups.rs Outdated
@greptile-apps
greptile-apps Bot dismissed their stale review July 22, 2026 18:17

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a06836f8f3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/features/groups.rs Outdated
Comment thread src/retry.rs
Comment thread wacore/src/send/group.rs
greptile-apps[bot]
greptile-apps Bot previously approved these changes Jul 22, 2026
@greptile-apps
greptile-apps Bot dismissed their stale review July 22, 2026 18:56

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

greptile-apps[bot]
greptile-apps Bot previously approved these changes Jul 22, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5002f893d8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread wacore/src/iq/usync.rs
Comment thread src/usync.rs Outdated
Comment thread src/retry.rs
@greptile-apps
greptile-apps Bot dismissed their stale review July 22, 2026 19:43

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

greptile-apps[bot]
greptile-apps Bot previously approved these changes Jul 22, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d6b8f9a529

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/retry.rs
"recipient is only valid for direct retransmissions".into(),
));
}
if recipient.is_some_and(|recipient| {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bind direct retransmission routing to the declared chat

When a public direct retransmission supplies chat=A but requester=B without a recipient, or supplies a recipient unrelated to chat, this validation accepts it. The pairwise builder then routes the stanza to the requester/recipient while chat is used only as the recent-message cache key, so the operation can report success after retransmitting A's message in B's conversation. Automatic retry parsing inherently keeps these identities aligned; reject public requests unless the direct chat matches the requester when recipient is absent, or matches the recipient through PN/LID aliases when it is present.

Useful? React with 👍 / 👎.

@greptile-apps
greptile-apps Bot dismissed their stale review July 22, 2026 20:29

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

greptile-apps[bot]
greptile-apps Bot previously approved these changes Jul 22, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 43c5aa3f4e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/retry.rs Outdated
Comment on lines +352 to +355
if matches!(route, RetransmissionRoute::Direct) {
let routing_chat = request.recipient.as_ref().unwrap_or(&request.requester);
if !self
.jids_share_user_identity(&request.chat, routing_chat)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Restrict recipient routes to peer devices and bots

Fresh evidence beyond the earlier chat-binding report is that chat=A, recipient=A, requester=B still passes this check for any unrelated nonlocal, non-bot user B, because only the chat and recipient identities are compared. The pairwise builder then encrypts A's message to B while labeling A as the recipient, even though with_recipient documents this route for self-device and bot retries. Require a recipient-bearing requester to be a local device or bot before advancing its session.

Useful? React with 👍 / 👎.

Comment thread src/usync.rs
Comment on lines +251 to +255
if !self
.device_topology
.registry_unchanged_for(topology_generation, |user| {
device_response_contains_user(response, user)
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Retry refreshes after concurrent mapping changes

When a PN→LID mapping changes after the refresh IQ starts, this check still accepts the response because registry_unchanged_for filters out the mapping-only topology entries recorded by LidPnCache. Since learn_device_list_mappings applies the response before this check, an older response can replace the newer PN→LID mapping and publish its device list under the superseded identity, causing subsequent sends to resolve the wrong Signal namespace. Include relevant mapping changes in the CAS/retry decision, while excluding only mappings learned from the response being committed.

Useful? React with 👍 / 👎.

@greptile-apps
greptile-apps Bot dismissed their stale review July 22, 2026 20:55

Dismissed because a newer commit was pushed; Greptile will re-review the current head.

@jlucaso1
jlucaso1 merged commit 013a328 into main Jul 22, 2026
16 checks passed
@jlucaso1
jlucaso1 deleted the agent/targeted-retransmission-controls branch July 22, 2026 21:02

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e241c5e248

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/features/groups.rs
Comment on lines +450 to +451
metadata.cache(Arc::clone(&info)).await;
return Ok(info);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Revalidate cold group snapshots after queued notifications

When the L1 cache is empty but persisted metadata exists, an add/remove notification arriving while the group IQ is in flight blocks on the cold_metadata lock; this branch then republishes and returns the pre-notification snapshot before the queued handler can apply its change. Fresh evidence beyond the prior warm-response race is that send_group_branch retains this returned Arc without rereading the cache after the notification obtains the lane, and outgoing sends are not otherwise per-chat locked, so the send can compute its phash and SKDM fanout from a removed or missing participant set. Revalidate the snapshot against a notification generation before returning it or retry after releasing the lane.

AGENTS.md reference: AGENTS.md:L27-L29

Useful? React with 👍 / 👎.

Comment thread src/usync.rs
Comment on lines +165 to +169
jids = response
.device_lists
.into_iter()
.map(|user| user.user)
.collect();

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve original identities when retrying refreshes

When the CAS rejects a response because a relevant PN→LID mapping changed, this replaces the original query identities with the rejected response's canonical JIDs. Fresh evidence beyond the earlier mapping-change report is that the refresh now retries, but seeds that retry from the stale response: if PN X returned LID Y while X concurrently remapped to Z, the next attempt queries obsolete Y and can relearn X→Y or return Y's devices as the authoritative result for X. Keep the original requested JIDs across attempts, or recanonicalize them through the current mapping after the CAS failure.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant