Root cause: WhatsApp Web stores pkmsg as ciphertext first, then decrypts
to interactive. React does not re-render the ciphertext→interactive
transition, requiring F5. When enc type is msg (established session),
Web receives as interactive directly and renders in real-time.
Changes:
- messages-send.ts: re-enable biz node for carousel (CDP evidence from
Pastorini confirms native_flow v=9 name=mixed + quality_control),
LID-based addressing for session reuse, blocking tctoken fetch,
force device-identity, skip bot node for carousel
- messages.ts: interactiveMessage direct (no viewOnceMessage wrapper),
skip Message.create() for carousel (oneOf corruption), skip ephemeral
contextInfo for carousel
- messages-media.ts: fix jimp type check (function not object)
- tc-token-utils.ts: dual storage under LID and PN for reliable lookup
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Wire onNewJidStored callback in messages-send.ts so proactively
fetched tokens are registered in the pruning index
- Batch keystore reads in pruneExpiredTcTokens (1 query instead of N)
- Persist lastTcTokenPruneTs in keystore so 24h throttle survives restarts
- Replace parseInt() with Number() for safer timestamp parsing
- Normalize JIDs via jidNormalizedUser() before LID lookup in
resolveTcTokenJid to prevent device-suffix mismatches
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>