Skip to content

docs: document source-aware LID-PN write policy (whatsapp-rust#1011) - #400

Merged
jlucaso1 merged 4 commits into
mainfrom
claude/nifty-bohr-ef4l0e
Jul 8, 2026
Merged

jlucaso1 merged 4 commits into
mainfrom
claude/nifty-bohr-ef4l0e

Conversation

@jlucaso1

@jlucaso1 jlucaso1 commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Summary

Documents oxidezap/whatsapp-rust#1011, which changed the LID-PN cache from unconditional last-write-wins to a source-aware write policy matching WhatsApp Web's createLidPnMappings (switch (learningSource)):

  • Directed sources (Usync, PeerPnMessage, PeerLidMessage, RecipientLatestLid, MigrationSyncLatest, MigrationSyncOld, BlocklistActive, BlocklistInactive) overwrite the cache on any change.
  • Observational bulk sources (Other, Pairing, DeviceNotification) only ever seed a brand-new LID; a conflict with an already-known LID no longer clobbers it — instead a live LID query is queued and the authoritative result is learned under Usync.
  • MigrationSyncOld / BlocklistInactive are stamped created_at = 0 so they never outrank a fresher mapping.

Also folds in the companion behavior from #1010: the history-sync phoneNumberToLidMappings seed is tagged Other (not MigrationSyncLatest, which is now solely the live 1:1 LID migration flow's source), so it's correctly documented as an observational/conservative source.

What changed

  • api/client.mdxLearningSource reference: added a "Write policy" column to the table, plus explanatory paragraphs on directed vs. observational vs. stale-source behavior. Corrected the MigrationSyncLatest description (no longer the history-sync seed source) and the Other description (now covers the history-sync seed).
  • concepts/storage.mdx — Granular cache patching → LID-PN mappings: documented the new lid_pn_write_policy gate that runs before the existing timestamp-based conflict resolution, including the live-query reconcile path.
  • advanced/state-management.mdx — Cache patching strategy summary table: updated the LID-PN mappings row and added a short cross-reference to the fuller writeup in concepts/storage.mdx.

No changelog entry added per instructions (changelog entries are human-authored only).

Test plan

  • Verified the MigrationSyncLatest / Other source claims against the current whatsapp-rust source (src/client/lid_pn.rs, wacore/src/types/lid_pn.rs) — MigrationSyncLatest is only referenced by the live LID-migration-sync handler; the history-sync harvest uses Other.
  • Docs site preview (Mintlify) — not run in this environment.

Generated by Claude Code


Summary by cubic

Document the source‑aware LID–PN write policy to match WhatsApp Web: directed sources overwrite; observational sources only seed new LIDs and queue a live re‑resolve; stale sources write with created_at = 0 so fresher data wins. Updated the LearningSource reference (write‑policy column and a note that explains capacity‑bounded eviction), expanded storage docs (write gate and live reconcile), clarified that history‑sync seeds are Other while MigrationSyncLatest is only for the live migration flow, updated the state‑management summary row, and removed a redundant paragraph and a dangling fragment.

Written for commit 59fb90c. Summary will update on new commits.

The LID-PN cache no longer applies every learn unconditionally: the
LearningSource now also selects a write policy (directed sources overwrite,
observational bulk sources only seed new LIDs and trigger a live re-resolve
on conflict, stale sources are timestamp-floored) matching WhatsApp Web's
createLidPnMappings. Update the LearningSource reference table, the storage
cache-patching writeup, and the state-management cache-patching summary.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@jlucaso1, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 26 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 2111d185-511f-444c-b691-bbc9a3126dbb

📥 Commits

Reviewing files that changed from the base of the PR and between 94c4131 and 59fb90c.

📒 Files selected for processing (3)
  • advanced/state-management.mdx
  • api/client.mdx
  • concepts/storage.mdx

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.

@mintlify

mintlify Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
whatsapp-rust 🟢 Ready View Preview Jul 8, 2026, 11:09 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@cubic-dev-ai cubic-dev-ai 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.

All reported issues were addressed across 3 files

Confidence score: 5/5

  • Safe to merge after the addressed issues were fixed.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread advanced/state-management.mdx Outdated

@cubic-dev-ai cubic-dev-ai 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.

0 issues found across 1 file (changes from recent commits).

Auto-approved: Documentation-only update to describe source-aware LID-PN write policy.

Re-trigger cubic

@greptile-apps

greptile-apps Bot commented Jul 8, 2026

Copy link
Copy Markdown

Greptile Summary

This PR documents the source-aware LID-PN write policy introduced in whatsapp-rust#1011, replacing the previous unconditional last-write-wins behavior with a two-gate system that mirrors WhatsApp Web's createLidPnMappings switch (learningSource).

  • api/client.mdx: The LearningSource table gains a "Write policy" column and three-tier classification (Directed, Observational, Known-stale); a Note explains the exact/reverse-only match edge case for the capacity-bounded cache.
  • concepts/storage.mdx: Adds the source-aware gate step before the existing timestamp comparison in the LID-PN cache write path, including the live LidQuerySpec reconcile loop and no-recursion guarantee.
  • advanced/state-management.mdx: Updates the LID-PN row in the patching summary table and renames the "Fallback" column to "Fallback / conflict behavior" to accurately cover both paths.

Confidence Score: 5/5

Documentation-only change with no executable code; all cross-file links verified, source examples confirmed in previous review threads, and the layered write-policy description is internally consistent across all three files.

All three files only add or refine prose and table rows. The cross-references resolve to real headings in the repo. The MigrationSyncLatest/Other source attribution and the group-participant LearningSource::Other example were both verified against source in previous review threads and confirmed accurate. The two-gate ordering (source policy → timestamp comparison) is logically coherent and matches the described implementation.

No files require special attention.

Important Files Changed

Filename Overview
api/client.mdx Expanded LearningSource section with write-policy column, three-tier source classification (Directed/Observational/Known-stale), and a Note on exact/reverse-only match semantics; all cross-links verified valid
concepts/storage.mdx Added source-aware write policy gate explanation ahead of the existing timestamp-based conflict resolution, including the live-query reconcile path and no-loop guarantee
advanced/state-management.mdx Updated LID-PN row in the cache-patching summary table and renamed 'Fallback' column to 'Fallback / conflict behavior' to cover both the LID-PN conflict gate and the traditional fallback paths; newline added at EOF

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Incoming LID-PN pair\n+ LearningSource"] --> B{"Source type?"}
    B -->|"Directed\n(Usync, PeerPn/LidMessage,\nRecipientLatestLid,\nMigrationSyncLatest,\nMigrationSyncOld,\nBlocklistActive/Inactive)"| C{"Exact or\nreverse-only match?"}
    B -->|"Observational\n(Other, Pairing,\nDeviceNotification)"| D{"LID already known\nfor this phone?"}
    C -->|"Yes — self-consistent"| E["Re-affirm durability\n(no-op write)"]
    C -->|"No — conflict"| F{"Known-stale source?\n(MigrationSyncOld /\nBlocklistInactive)"}
    F -->|"Yes"| G["Set created_at = 0"]
    F -->|"No"| H["Use actual created_at"]
    G --> I{"Timestamp gate:\nnew created_at ≥ existing?"}
    H --> I
    I -->|"Yes"| J["Update PN→LID entry\n(LID→PN always updated)"]
    I -->|"No"| K["Skip PN→LID update\n(LID→PN still updated)"]
    D -->|"Not cached — no conflict"| L["Write as new seed\n(observational)"]
    D -->|"Conflict with known LID"| M["Skip write\nQueue LidQuerySpec"]
    M --> N["Background live LID query"]
    N --> O["Result learned as Usync\n(directed — no reconcile loop)"]
Loading
%%{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"}}}%%
flowchart TD
    A["Incoming LID-PN pair\n+ LearningSource"] --> B{"Source type?"}
    B -->|"Directed\n(Usync, PeerPn/LidMessage,\nRecipientLatestLid,\nMigrationSyncLatest,\nMigrationSyncOld,\nBlocklistActive/Inactive)"| C{"Exact or\nreverse-only match?"}
    B -->|"Observational\n(Other, Pairing,\nDeviceNotification)"| D{"LID already known\nfor this phone?"}
    C -->|"Yes — self-consistent"| E["Re-affirm durability\n(no-op write)"]
    C -->|"No — conflict"| F{"Known-stale source?\n(MigrationSyncOld /\nBlocklistInactive)"}
    F -->|"Yes"| G["Set created_at = 0"]
    F -->|"No"| H["Use actual created_at"]
    G --> I{"Timestamp gate:\nnew created_at ≥ existing?"}
    H --> I
    I -->|"Yes"| J["Update PN→LID entry\n(LID→PN always updated)"]
    I -->|"No"| K["Skip PN→LID update\n(LID→PN still updated)"]
    D -->|"Not cached — no conflict"| L["Write as new seed\n(observational)"]
    D -->|"Conflict with known LID"| M["Skip write\nQueue LidQuerySpec"]
    M --> N["Background live LID query"]
    N --> O["Result learned as Usync\n(directed — no reconcile loop)"]
Loading

Reviews (3): Last reviewed commit: "docs: address greptile style nits (redun..." | Re-trigger Greptile

Comment thread advanced/state-management.mdx Outdated
Comment thread concepts/storage.mdx
The summary table still listed the old three-source shorthand and framed
the write-policy gate as a post-hoc fallback, addressing greptile review
feedback on PR #400.

@cubic-dev-ai cubic-dev-ai 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.

0 issues found across 1 file (changes from recent commits).

Auto-approved: Documentation-only changes across three .mdx files. Updates describe source-aware LID-PN write policy behavior — no logic, config, infrastructure, or test changes.

Re-trigger cubic

greptile-apps[bot]
greptile-apps Bot previously approved these changes Jul 8, 2026
…gon)

Drop the state-management paragraph that duplicated both the summary
table and the following cross-reference link, and explain what
"capacity-bounded eviction" means in the LearningSource Note instead of
assuming reader familiarity with the cache config.
@greptile-apps
greptile-apps Bot dismissed their stale review July 8, 2026 23:19

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

@cubic-dev-ai cubic-dev-ai 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.

0 issues found across 2 files (changes from recent commits).

Auto-approved: Documentation-only changes: updated LearningSource table with write-policy column, expanded storage docs, and updated state-management summary. No code or logic changes.

Re-trigger cubic

@jlucaso1
jlucaso1 merged commit 85370c7 into main Jul 8, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants