Skip to content

release: develop → master 2026-06-08 (5 PRs)#521

Merged
rsalcara merged 11 commits into
masterfrom
release/develop-to-master-2026-06-08
Jun 8, 2026
Merged

release: develop → master 2026-06-08 (5 PRs)#521
rsalcara merged 11 commits into
masterfrom
release/develop-to-master-2026-06-08

Conversation

@rsalcara

@rsalcara rsalcara commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Merges 6 PRs landed on `develop` since the previous master sync (2026-06-06), preserves the two auto-bumps that have since landed on master (#516, #517), and ships them together. Zero merge conflictsdevelop never touched the auto-bumped files.

PRs in this release

PR Title
#514 chore(build): exclude .md from src→lib mirror — stops shipping internal architecture notes to consumer node_modules
#515 chore(logs): compact recoverable Signal Protocol failures — ~10KB → ~250B per event, level errorwarn for auto-recoverable
#518 feat(meta-ai): decrypt msmsg via empirically-validated WA Web algorithm — Meta AI / FBID bot replies now decrypt instead of NACKing
#519 feat(stickers): support lottieStickerMessage for animated .was stickers — wraps/unwraps so mobile renders them
#520 fix(decode): preserve outer messageContextInfo when unwrapping deviceSentMessage — closes #518's codex P1 (outgoing-side msmsg secret cache)

Preserved from master (NOT touched by this merge)

Develop never touched these files, so both bumps survive intact. Post-merge baileys-version.json:
```json
{"version":[2,3000,1040994085]}
```

Validation

  • ✅ Auto-merge succeeded with zero conflictsmessages-recv.ts was the only file modified on both sides, edits were non-overlapping, git resolved automatically.
  • ✅ `npm run build` clean on the merged tree
  • ✅ 57/57 tests pass across the new-PR suites
  • baileys-version.json post-merge confirms master's auto-bump preserved (NOT downgraded to develop's stale 1040973525)

Customizations preserved (NOT touched)

Carousel, lists, buttons, polls, view-once, biz quality_control, useLegacyLock, TC token custom flow, LID↔PN batched, Phase 9 multi-DB, lidDbMigrated:false, cacheMetricsInterval memory-leak fix, schema migrations + statement cache + busy retry.

🤖 Generated with Claude Code


Summary by cubic

Syncs develop to master with Meta AI msmsg decryption and Lottie animated sticker support, plus audit and lint fixes that preserve DSM context-info, cut noisy logs, and avoid pointless retries. Keeps master’s WA version bumps and stops shipping .md files in lib/.

  • New Features

    • Decrypt <enc type="msmsg"> for Meta AI/FBID bots using the WA Web algorithm with a per-socket secret cache (1h TTL, 500 keys) cleared/closed on disconnect.
    • Add lottieStickerMessage support for .was stickers: wrap on send and unwrap on read so mobile renders them; set mediatype="sticker" on send.
  • Bug Fixes

    • Preserve and lift messageContextInfo across deviceSentMessage unwrap and DSM (initial and retry, incl. Lottie) so messageSecret and reporting tokens are retained.
    • ACK only orphan msmsg replies (narrow match: no messageSecret for ...), while other decryptMsmsgBotMessage failures follow the Signal retry path.
    • Log recoverable Signal errors as compact warn via compactError; downgrade transactWith rollback logs to trace.
    • Satisfy eqeqeq with explicit null checks in compactError; remove an unused import in meta-ai-msmsg.

Written for commit 2ec8ba3. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Meta AI/FBID bot encrypted messages: per-connection secret caching and in-place decryption.
    • Lottie animated sticker support with proper message-context handling and routing.
  • Improvements

    • More compact, recoverable error logging and reduced log noise for certain corruption cases.
    • Smarter message-secret/cache handling and preserved reporting tokens for Lottie sends; fewer unnecessary retries.
  • Chores

    • Build: Markdown files are now excluded from asset mirroring.
  • Tests

    • Comprehensive tests for msmsg decryption, Lottie handling, and message-context preservation.

rsalcara and others added 7 commits June 6, 2026 23:41
…f path (#513 review)

PR #513 chatgpt-codex review (P2) caught a real gap that PR #509 introduced
when it added the `maxKeys` cap to `userDevicesCache`:

  - PR #509 added `safeCacheSet` handling to the cache-population path in
    `messages-send.ts:528-548` (where USync fills the cache).
  - The OTHER call-site that writes to `userDevicesCache` —
    `messages-recv.ts:2240` in the device-notification handler ('add' /
    'remove' tags) — was left unprotected.

`@cacheable/node-cache`'s capacity check is `keyCount() + 1 > maxKeys` —
applied BEFORE the engine checks whether the key already exists. So once
the cache reaches its `maxKeys` ceiling (5,000 entries), even an UPDATE
to an already-cached user throws ECACHEFULL. The guard
`if (!existingCache.length) continue` at line 2210 doesn't help: it only
short-circuits when the user is NOT cached. A device-list update for an
already-cached user would still hit the `.set` and throw.

Real impact under sustained gateway load:

  - Cache hits 5,000 entries (a few dozen active groups will get there).
  - A device-add/remove notification arrives for one of the cached users.
  - `userDevicesCache.set(...)` throws ECACHEFULL.
  - The throw propagates into the message-receive handler and lands in
    Baileys' outer error boundary — connection survives, but a log-level
    error is emitted and the affected user's device list is NOT updated
    in the cache.
  - Next message-send for that user fetches the fresh list via USync
    (`getUSyncDevices`), which IS guarded — so the durable behavior
    eventually recovers.

The fix routes the device-notif write through the same `safeCacheSet`
helper PR #509 used in messages-send.ts. Same swallow-ECACHEFULL semantics,
same debug log, same `getUSyncDevices` fallback path. Symmetric handling
across the two call-sites that update the cache.

Test plan:
  - npm run build ✓ (3 phases pass, zero errors)
  - 1 line of production change in `messages-recv.ts:2240`, plus comment
    explaining the WHY. No test changes needed — `safeCacheSet`'s
    behavior is already covered by `cache-utils.test.ts`.

Out of scope (intentionally NOT touched):
  - Carousel, lists, buttons, polls, view-once, biz quality_control,
    useLegacyLock, TC token custom flow, LID↔PN batched, Phase 9 multi-DB,
    lidDbMigrated:false, the cacheMetricsInterval memory-leak fix, schema
    migrations + statement cache + busy retry.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…514)

chore(build): exclude .md from src→lib mirror (keep docs repo-local) (#514)
chore(logs): compact recoverable Signal Protocol failures (#515)
…hm (#518)

feat(meta-ai): decrypt msmsg via empirically-validated WA Web algorithm (#518)
…rs (#519)

feat(stickers): support lottieStickerMessage for animated .was stickers (#519)
…SentMessage (#520)

fix(decode): preserve outer messageContextInfo when unwrapping deviceSentMessage (#520)
Merges 6 PRs landed on `develop` since the previous master sync
(2026-06-06), preserves the two auto-bumps that have since landed on
master (#516, #517), and ships them together.

PRs included in this release
============================

  * #514 — chore(build): exclude .md from src→lib mirror
    Internal architecture notes (`src/Utils/multi-db-sqlite/ARCHITECTURE.md`,
    `USAGE.md`) no longer ship in the published package. Disk savings on
    consumer side + stops leaking internal phase planning into anyone
    that runs `npm install`.

  * #515 — chore(logs): compact recoverable Signal Protocol failures
    Recoverable Signal failures (Bad MAC, MessageCounterError, old
    counter, Invalid PreKey ID) are now compact one-liners at `warn`
    instead of three multi-KB `error` entries each. Per-event log
    output: ~10KB → ~250B. Unknown errors keep full stack + stanza.
    Net: error-dashboard noise drops dramatically without losing
    real signal.

  * #518 — feat(meta-ai): decrypt msmsg via empirically-validated WA Web
    Meta AI / FBID-bot replies (`<enc type="msmsg">`) now decrypt
    instead of NACKing with MissingMessageSecret. Algorithm
    reverse-engineered from `WAWebBotMessageSecret` via CDP and
    validated LIVE with a Meta AI "oi" capture. Five distinct bugs in
    upstream PR WhiskeySockets#2592 fixed (unbounded cache, cross-tenant leak, no
    FBID dispatch, drops streaming chunks, raw-id cache key, 12-strat
    brute force). Per-socket bounded LRU + `flushAll() + close()` on
    socket end to release the NodeCache timer.

  * #519 — feat(stickers): support lottieStickerMessage for animated .was
    Wraps + unwraps Lottie stickers (`application/was`) in
    `lottieStickerMessage` (FutureProofMessage at proto field 74),
    matching `WAWebE2EProtoGenerator`'s actual implementation. Mobile
    clients silently drop Lottie stickers in the unwrapped form; this
    makes them render on Android/iOS. Send-path `getMediaType` +
    DSM `messageContextInfo` reads both walk the wrap correctly.

  * #520 — fix(decode): preserve outer messageContextInfo when
    unwrapping deviceSentMessage
    Closes the codex P1 gap left deferred from #518. When WhatsApp
    delivers a fromMe-via-linked-device message, the OUTER `Message`
    carries `messageContextInfo.messageSecret` and the inner does not
    — the previous `msg = msg.deviceSentMessage?.message || msg`
    dropped that secret entirely. New `unwrapDeviceSentMessage` does a
    per-field merge matching WA Web's `l(e)` source exactly, including
    a length-check guard on `threadId` (protobuf decodes empty
    `repeated` as `[]` not `undefined` — naive `??` would lose the
    outer thread context).

  * #513 follow-up (already on master as `373a6f3622` from previous
    release) — the develop-side commit `50f9a77ef8` is the same
    change. Merge collapses both onto the master line; no behaviour
    change.

Preserved from master (NOT touched by this merge)
==================================================

  * #516 — chore: update proto/version to v2.3000.1040989513
    Auto-bumped `WAProto/WAProto.proto` + `baileys-version.json`.
    develop never touched these files, so the bump survives intact.
  * #517 — chore: update WhatsApp Web version to v2.3000.1040994085
    Auto-bumped `baileys-version.json` again. Same — develop didn't
    touch it, master's value (`{"version":[2,3000,1040994085]}`) is
    preserved verbatim post-merge.

Validation
==========

  * Auto-merge succeeded with ZERO conflicts — `messages-recv.ts` was
    the only file modified on both sides, but the edits were
    non-overlapping and git resolved them automatically.
  * `npm run build` clean on the merged tree.
  * 57/57 tests pass across the new-PR suites
    (dsm-context-info + meta-ai-msmsg + lottie-sticker-message +
    error-log-utils + process-message.protocol-guard).
  * `baileys-version.json` post-merge: `{"version":[2,3000,1040994085]}`
    — confirms master's auto-bump was preserved (NOT downgraded to
    develop's stale `1040973525`).

Customizations preserved (NOT touched)
======================================

Carrossel, lists, buttons, polls, view-once, biz `quality_control`,
`useLegacyLock`, TC token custom flow, LID↔PN batched, Phase 9
multi-DB, `lidDbMigrated:false`, `cacheMetricsInterval` memory-leak
fix, schema migrations + statement cache + busy retry.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 8, 2026 01:24
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

Thanks for opening this pull request and contributing to the project!

The next step is for the maintainers to review your changes. If everything looks good, it will be approved and merged into the main branch.

In the meantime, anyone in the community is encouraged to test this pull request and provide feedback.

✅ How to confirm it works

If you’ve tested this PR, please comment below with:

Tested and working ✅

This helps us speed up the review and merge process.

📦 To test this PR locally:

# NPM
npm install @whiskeysockets/baileys@rsalcara/InfiniteAPI#release/develop-to-master-2026-06-08

# Yarn (v2+)
yarn add @whiskeysockets/baileys@rsalcara/InfiniteAPI#release/develop-to-master-2026-06-08

# PNPM
pnpm add @whiskeysockets/baileys@rsalcara/InfiniteAPI#release/develop-to-master-2026-06-08

If you encounter any issues or have feedback, feel free to comment as well.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6a4029f8-1971-4268-a01f-ed372e5f4ee5

📥 Commits

Reviewing files that changed from the base of the PR and between b2c5abf and 2ec8ba3.

📒 Files selected for processing (1)
  • src/Socket/messages-recv.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/Socket/messages-recv.ts

📝 Walkthrough

Walkthrough

Adds WA Web–validated msmsg decryption with a per-socket secret cache, unwraps deviceSentMessage envelopes preserving DSM fields, supports Lottie sticker wrapping/unwrapping and DSM context, compacts error logging, wires defaults, and adds comprehensive tests.

Changes

Meta AI msmsg decryption and Lottie sticker handling

Layer / File(s) Summary
Error logging, cache helper, and re-exports
src/Utils/error-log-utils.ts, src/Utils/cache-utils.ts, src/Utils/index.ts, src/__tests__/Utils/error-log-utils.test.ts
Adds compactError(err) for compact, non-throwing error strings; exports isNodeCacheFullError and re-exports new utils. Tests pin formatting and non-throwing behavior.
Lottie sticker wrapping, normalization, and DSM context
src/Utils/messages.ts, src/Socket/messages-send.ts, src/__tests__/Utils/lottie-sticker-message.test.ts, src/__tests__/Utils/dsm-context-info-preservation.test.ts
Detects Lottie stickers (application/was / isLottie), wraps outgoing payload in lottieStickerMessage, unwraps during normalization, and ensures DSM messageContextInfo is read from the inner wrapper. Tests validate unwrapping, proto round-trip preservation, DSM reader locations, and field-precedence merge semantics for messageContextInfo.
Meta AI msmsg decryption core
src/Utils/meta-ai-msmsg.ts, src/__tests__/Utils/meta-ai-msmsg.test.ts, src/Defaults/index.ts, scripts/copy-assets.mjs
New module: stanza metadata extraction, WAWeb-shaped cache keys, per-socket TTL secret cache, OrphanMsmsgError, HKDF-based key derivation and AES-256-GCM decryption with AAD, plaintext unpad+proto decode, FBID vs non-FBID handling, and classification helpers. Adds MSMSG_SECRET defaults and skips .md in asset copying. Crypto and cache behaviors covered by tests.
Decode pipeline integration and DSM envelope merge
src/Utils/decode-wa-message.ts, src/__tests__/Utils/dsm-context-info-preservation.test.ts
decryptMessageNode accepts optional msmsgCache, adds enc type="msmsg" branch using decryptMsmsgBotMessage, exports unwrapDeviceSentMessage with field-preserving merge semantics, caches messageSecret when present, and refactors decrypt error logging to use compact error strings.
Socket lifecycle, per-socket cache, and recv handling
src/Socket/messages-recv.ts
Creates per-socket msmsgSecretCache, passes it into decryption calls, flushes and close()s the cache on socket end to avoid secret/timer leakage, routes msmsg stanzas into the new decrypt flow, and ACKs orphan-msmsg decrypt stubs to avoid retry churn; corrupted-session errors emit compact warnings.
Small supporting changes
src/Utils/auth-utils.ts, src/Utils/cache-utils.ts
Downgrades a rollback catch log to trace-only string output and exports isNodeCacheFullError for reuse in safe cache writes.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • rsalcara/InfiniteAPI#457: Both PRs modify the transactWith implementation in src/Utils/auth-utils.ts (overlap at transactWith code level).
  • rsalcara/InfiniteAPI#444: Overlaps inbound receive ACK/NACK handling and retry prevention changes in src/Socket/messages-recv.ts.
  • rsalcara/InfiniteAPI#472: Related edits to scripts/copy-assets.mjs; #472 introduced the asset mirroring CLI that this PR extends by skipping .md.

"🐰 In hkdf fields and AES-GCM light,
Lottie stickers twirl in flight.
Secrets kept per socket tight,
Compact logs keep warnings slight.
Bots reply — now we read them right."

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'release: develop → master 2026-06-08 (5 PRs)' accurately summarizes a release merge that consolidates five PRs from develop to master, which aligns with the core objective of this changeset.
Linked Issues check ✅ Passed All linked issue #518 objectives are comprehensively met: msmsg decryption via HKDF+AES-256-GCM is implemented, per-socket cache with configurable TTL/maxKeys is added, FBID vs regular bot distinction is handled, tri-partite cache keys matching WAWebMsgKey are used, and integration with tests is complete.
Out of Scope Changes check ✅ Passed All changes are in scope: build exclusion of .md files, log compaction for Signal Protocol errors, msmsg decryption infrastructure, Lottie sticker wrapping, and deviceSentMessage unwrapping directly support the release objectives and linked issue #518 requirements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch release/develop-to-master-2026-06-08

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.

Warning

Billing warning: we have not been able to collect payment for this subscription for more than 72 hours. Please update the payment method or pay any pending invoices in Billing to avoid service interruption.


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

@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: bb614011c6

ℹ️ 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/Utils/messages.ts
Comment thread src/Utils/decode-wa-message.ts

Copilot AI 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.

Pull request overview

This release PR synchronizes develop into master, bundling multiple recently-landed changes across build packaging, message decryption/handling, and operational logging.

Changes:

  • Adjust build asset mirroring to avoid publishing repo-local Markdown docs into lib/.
  • Add Meta AI / FBID <enc type="msmsg"> decryption support with a per-socket messageSecret cache, plus DSM context preservation and log compaction for recoverable Signal failures.
  • Add full send/receive support for Lottie .was stickers via lottieStickerMessage wrapping/unwrapping, including send-path metadata handling.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/Utils/meta-ai-msmsg.ts Implements msmsg stanza parsing, per-socket secret cache, HKDF+AES-GCM decryption, and secret auto-caching.
src/Utils/messages.ts Wraps outgoing Lottie stickers in lottieStickerMessage and unwraps them during normalization.
src/Utils/index.ts Re-exports newly added utilities (error logging + msmsg helpers) from the Utils barrel.
src/Utils/error-log-utils.ts Adds compactError() helper to log recoverable errors without large stacks.
src/Utils/decode-wa-message.ts Adds msmsg decode path, caches message secrets post-decrypt, preserves DSM outer messageContextInfo, and compacts logging for known recoverable failures.
src/Utils/cache-utils.ts Exports isNodeCacheFullError so other modules can safely guard NodeCache saturation errors.
src/Utils/auth-utils.ts Downgrades transaction rollback logging noise (error→trace) for expected rollback paths.
src/Socket/messages-send.ts Ensures DSM context info is read correctly when sending wrapped Lottie stickers; fixes mediaType detection for the wrapper.
src/Socket/messages-recv.ts Wires a per-socket msmsg secret cache into decrypt flow; removes unconditional msmsg NACK; compacts logs for recoverable session errors.
src/Defaults/index.ts Adds default TTL/maxKeys for the msmsg secret cache.
src/tests/Utils/meta-ai-msmsg.test.ts Adds unit tests covering cache keying, stanza parsing, error behavior, and crypto roundtrips for msmsg.
src/tests/Utils/lottie-sticker-message.test.ts Adds round-trip and shape-pin tests for Lottie sticker wrapping/unwrapping and send-path contracts.
src/tests/Utils/error-log-utils.test.ts Adds tests pinning compactError() formatting and “must never throw” behavior.
src/tests/Utils/dsm-context-info-preservation.test.ts Adds regression tests pinning DSM outer/inner messageContextInfo merge semantics.
scripts/copy-assets.mjs Excludes .md from srclib mirroring to avoid shipping internal docs to consumers.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/Utils/auth-utils.ts Outdated
Comment thread src/Utils/meta-ai-msmsg.ts 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: 1

🧹 Nitpick comments (1)
src/Utils/auth-utils.ts (1)

710-714: ⚡ Quick win

Keep compact rollback logs, but include structured error detail instead of message-only.

err?.message drops stack/name/code/cause, which reduces debuggability for unexpected rollback failures. Consider logging a compact structured form (e.g., compactError(err)) at trace level to keep noise low without losing key diagnostics.

🤖 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/Utils/auth-utils.ts` around lines 710 - 714, The rollback trace currently
logs only err?.message which loses useful diagnostics; update the rollback
logging (the logger.trace call that logs 'transactWith rolled back') to pass a
compact structured error object instead (e.g., call a helper compactError(err)
that preserves name/code/message/stack/cause but keeps it short) so trace-level
output remains low-noise yet debuggable; implement compactError(err) (or reuse
an existing error-formatter) and replace logger.trace({ err: (err as
any)?.message }, 'transactWith rolled back') with logger.trace({ err:
compactError(err) }, 'transactWith rolled back') in the transactWith/rollback
path.
🤖 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/Socket/messages-send.ts`:
- Around line 1190-1198: The retry-resend path rebuilds deviceSentMessage
without carrying over messageContextInfo, so replicate the same DSM context
logic used when constructing meMsg: compute dsmMessageContextInfo from
message.lottieStickerMessage?.message?.messageContextInfo ??
message.messageContextInfo and ensure any rebuilt deviceSentMessage (the object
created during the retry/resend flow) includes messageContextInfo:
dsmMessageContextInfo; update the retry/resend code path that reconstructs
deviceSentMessage to copy this messageContextInfo field so wrapped Lottie
stickers retain messageSecret/reporting tokens.

---

Nitpick comments:
In `@src/Utils/auth-utils.ts`:
- Around line 710-714: The rollback trace currently logs only err?.message which
loses useful diagnostics; update the rollback logging (the logger.trace call
that logs 'transactWith rolled back') to pass a compact structured error object
instead (e.g., call a helper compactError(err) that preserves
name/code/message/stack/cause but keeps it short) so trace-level output remains
low-noise yet debuggable; implement compactError(err) (or reuse an existing
error-formatter) and replace logger.trace({ err: (err as any)?.message },
'transactWith rolled back') with logger.trace({ err: compactError(err) },
'transactWith rolled back') in the transactWith/rollback path.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 34f07706-9fd2-4ff9-b023-e6fa96d5f8db

📥 Commits

Reviewing files that changed from the base of the PR and between b5d1bab and bb61401.

📒 Files selected for processing (15)
  • scripts/copy-assets.mjs
  • src/Defaults/index.ts
  • src/Socket/messages-recv.ts
  • src/Socket/messages-send.ts
  • src/Utils/auth-utils.ts
  • src/Utils/cache-utils.ts
  • src/Utils/decode-wa-message.ts
  • src/Utils/error-log-utils.ts
  • src/Utils/index.ts
  • src/Utils/messages.ts
  • src/Utils/meta-ai-msmsg.ts
  • src/__tests__/Utils/dsm-context-info-preservation.test.ts
  • src/__tests__/Utils/error-log-utils.test.ts
  • src/__tests__/Utils/lottie-sticker-message.test.ts
  • src/__tests__/Utils/meta-ai-msmsg.test.ts

Comment thread src/Socket/messages-send.ts

@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.

5 issues found across 15 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/Utils/decode-wa-message.ts">

<violation number="1" location="src/Utils/decode-wa-message.ts:685">
P2: When `OrphanMsmsgError` is thrown (no `messageSecret` in cache), it propagates to the outer catch in `messages-recv.ts` which sends a generic error NACK. The previous code explicitly sent `NACK_REASONS.MissingMessageSecret` for msmsg stanzas. The generic NACK causes the server to enter the Signal retry path, which cannot recover a missing msmsg cache entry — the retry will fail identically each time. Consider catching `OrphanMsmsgError` specifically in the outer handler and sending `NACK_REASONS.MissingMessageSecret` to preserve the intended NACK semantics and avoid pointless retries.</violation>
</file>

<file name="src/Utils/messages.ts">

<violation number="1" location="src/Utils/messages.ts:1887">
P2: After the Lottie wrap (`m = { lottieStickerMessage: { message: m } }`), the top-level `m.messageContextInfo` is `undefined` — the secret moved inside the wrapper. The send path's reporting-token logic reads `reportingMessage.messageContextInfo?.messageSecret` from the top level, so Lottie sticker sends will silently skip the `reporting_token` attachment. Either preserve `messageContextInfo` at the top level of the wrapped message or teach the reporting-token path to look inside the wrapper (similar to the `dsmMessageContextInfo` fix applied for the DSM envelope).</violation>
</file>

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

Re-trigger cubic

Comment thread src/Socket/messages-send.ts
Comment thread src/Utils/decode-wa-message.ts
Comment thread src/__tests__/Utils/dsm-context-info-preservation.test.ts Outdated
Comment thread src/Utils/error-log-utils.ts Outdated
Comment thread src/Utils/messages.ts
rsalcara and others added 2 commits June 7, 2026 23:02
5 findings from the release PR #521 audit applied before promoting
develop → master. The release branch itself doesn't change; this PR
lands the fixes on develop and the release branch will be refreshed
to include them.

P2 — Thread 1 (chatgpt) — reporting-token check reads outer wrap
================================================================

`messages-send.ts:1884` gated reporting-token attachment on
`reportingMessage?.messageContextInfo?.messageSecret`. For Lottie
stickers post-PR #519 that secret lives INSIDE the
`lottieStickerMessage` wrap — the top-level read returns undefined
and the token is silently skipped. Regression vs plain sticker
behaviour.

Fix: lift `messageContextInfo` from both locations the same way the
initial-fanout DSM read does (the lift PR #519 already shipped on
line ~1198):

    const reportingMessageSecret =
      reportingMessage?.lottieStickerMessage?.message
        ?.messageContextInfo?.messageSecret
      ?? reportingMessage?.messageContextInfo?.messageSecret

Required adding `reportingMessage &&` to the surrounding `if` so
TypeScript doesn't lose the narrowing it previously got from the
inline property chain (the narrowing was the side-effect of reading
`reportingMessage.messageContextInfo` in the condition itself).

P2 — Thread 5 (coderabbit Major) — retry-resend DSM drops messageContextInfo
============================================================================

`messages-send.ts:1580` rebuilds the `deviceSentMessage` envelope on
the retry-resend path WITHOUT carrying `messageContextInfo` along.
The initial-fanout path got the lift in PR #519 (line ~1198); the
retry path was missed.

Concrete impact: when a companion device receives the RETRY of a
Lottie sticker via DSM, our own `unwrapDeviceSentMessage` finds:
  - inner = messageToSend = { lottieStickerMessage: { message: { stickerMessage, messageContextInfo } } }
  - inner.messageContextInfo = undefined (it's nested in the wrap)
  - outer.messageContextInfo = undefined (the retry envelope omitted it)
  → messageSecret = undefined, reporting token / encrypted-edit
    decryption material lost on the companion's copy.

Fix: same lift inline at the retry envelope build site.

P2 — Thread 2 (chatgpt) — OrphanMsmsgError stub goes to Signal retry path
=========================================================================

When `decryptMsmsgBotMessage` raises `OrphanMsmsgError` (cache miss),
the catch in `decode-wa-message.ts` sets
`messageStubType = CIPHERTEXT` and
`messageStubParameters[0] = String(err.message)`. The receive handler
at `messages-recv.ts:3115` checks for known stub-param strings and
falls through to the Signal retry / PDO placeholder-resend path when
none match — burning retry budget asking the bot for prekeys it has
no business issuing, for a problem (missing CACHE entry) that a
Signal retry can never fix.

Fix: add a guard for `messageStubParameters[0]?.startsWith('decryptMsmsgBotMessage:')`
right after the `MISSING_KEYS_ERROR_TEXT` branch. Plain ACK (no NACK,
no retry) so the server considers the message delivered. The next
bot reply that arrives after the outgoing-secret cache populates
will decrypt cleanly.

NOT a NACK MissingMessageSecret: that would tell the server to
retransmit, and the retransmission will hit the same orphan state
until the outgoing-side cache is populated (deferred per PR #518).

P3 — Thread 4 (copilot) — `__internal` export not consumed
==========================================================

`src/Utils/meta-ai-msmsg.ts` exported an `__internal` bag of helpers
(`BOT_MESSAGE_INFO`, `KEY_LENGTH`, `isMeJid`, `deriveKeyAndDecrypt`,
`decodeDecryptedMsmsg`, `userOnlyJid`, `isJidGroup`) that no file in
the repo actually imports. Grep confirms zero call sites. Removed —
the helpers stay module-private as intended.

P3 — Thread 3 (copilot) — `(err as any)?.message` in auth-utils
===============================================================

`src/Utils/auth-utils.ts:714` (the trace I added in PR #515 to log
`transactWith rolled back` without duplicating the stack) used a
plain `(err as any)?.message` cast. Tightened to
`err instanceof Error ? err.message : String(err)` — no runtime
change, just removes the `any` cast and gives string fallback for
non-Error throws.

Validation
==========

  * `npm run build` clean (TS narrowing fixed via explicit
    `reportingMessage &&` guard).
  * 57/57 tests pass across the new-PR suites
    (dsm-context-info-preservation + meta-ai-msmsg +
    lottie-sticker-message + error-log-utils +
    process-message.protocol-guard).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Two findings from the cubic re-review on PR #521 that the previous
audit-fix commit (cherry-picked from closed PR #522) didn't cover.

Issue D (P2) — test re-implemented production helper
====================================================

cubic thread 8: `dsm-context-info-preservation.test.ts` kept a local
copy of `unwrapDeviceSentMessage` and asserted against it. Comment
claimed "if rules change in decode-wa-message.ts these break first"
but that was wrong — the assertions tested the LOCAL copy, not
production. Reverting `decode-wa-message.ts` to the old `msg =
msg.deviceSentMessage?.message || msg` would leave all 10 tests
green. The tests were validating themselves.

Fix:
  * `decode-wa-message.ts` — flipped the helper from module-private
    `const` to `export const unwrapDeviceSentMessage`. The function is
    a leaf utility; exporting it surfaces nothing operational beyond
    what tests need.
  * `dsm-context-info-preservation.test.ts` — deleted the re-derived
    copy, imported from `../../Utils/decode-wa-message`. Header
    comment updated to explain WHY we now import (production parity)
    instead of re-derive.

Issue E (P3) — `if (!err)` too broad in compactError
====================================================

cubic thread 9: `error-log-utils.ts:33` short-circuited every falsy
input (including `0`, `''`, `false`, `NaN`) to the literal string
`'Unknown'`. Those are unusual but valid thrown values — code that
does `throw 0` would get its actual value erased. Operational impact
near zero (Signal Protocol throws `Error` instances), but the
contract is wrong.

Fix:
  * `error-log-utils.ts` — `if (!err)` → `if (err == null)`. Comment
    added explaining the nullish-only narrowing.
  * `error-log-utils.test.ts` — new test `preserves falsy primitives
    that are NOT null/undefined` pins the new contract: `compactError(0)`
    → `'0'`, `compactError(false)` → `'false'`, etc.

Validation
==========

  * `npm run build` clean
  * 58/58 tests pass (5 suites: dsm-context-info + error-log-utils +
    meta-ai-msmsg + lottie-sticker-message + process-message).
    Was 57; +1 from the new falsy-primitives test.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

@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/Utils/error-log-utils.ts`:
- Line 36: Replace the loose equality check "if (err == null) return 'Unknown'"
with an explicit nullish check to satisfy ESLint eqeqeq: detect both null and
undefined (e.g., use "err === null || err === undefined") and return 'Unknown'
in that case; update the condition in the same spot where the variable err is
checked in error-log-utils.ts so behavior is unchanged but linting passes.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1fda62ed-1070-42c3-b550-b724a718d301

📥 Commits

Reviewing files that changed from the base of the PR and between bb61401 and 4214847.

📒 Files selected for processing (8)
  • src/Socket/messages-recv.ts
  • src/Socket/messages-send.ts
  • src/Utils/auth-utils.ts
  • src/Utils/decode-wa-message.ts
  • src/Utils/error-log-utils.ts
  • src/Utils/meta-ai-msmsg.ts
  • src/__tests__/Utils/dsm-context-info-preservation.test.ts
  • src/__tests__/Utils/error-log-utils.test.ts
💤 Files with no reviewable changes (1)
  • src/Utils/meta-ai-msmsg.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/tests/Utils/error-log-utils.test.ts
  • src/Socket/messages-recv.ts
  • src/Utils/decode-wa-message.ts

Comment thread src/Utils/error-log-utils.ts 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.

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

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

Re-trigger cubic

Comment thread src/Utils/auth-utils.ts
Comment thread src/Socket/messages-recv.ts Outdated
rsalcara and others added 2 commits June 7, 2026 23:18
CI lint failed on the previous commit:
  - error-log-utils.ts:36 — `if (err == null)` violated the codebase's
    `eqeqeq` rule even though `== null` is the idiomatic nullish check.
    Expanded to `if (err === null || err === undefined)` for the same
    semantics with strict-equality compliance.
  - meta-ai-msmsg.ts:46 — `isJidGroup` was imported but its only
    consumer (the now-removed `__internal` export bag from cubic
    audit thread 4) is gone. Removed from the import list.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
cubic re-review (thread 13, confidence 9) caught that the previous
ACK guard was too broad:

  if (msg?.messageStubParameters?.[0]?.startsWith('decryptMsmsgBotMessage:'))

`decryptMsmsgBotMessage` throws with a `decryptMsmsgBotMessage:` prefix
for several distinct conditions, not just `OrphanMsmsgError`:

  - `'decryptMsmsgBotMessage: no messageSecret for ${cacheKey}'`
    ← OrphanMsmsgError — cache miss, ACK + wait for cache to populate
  - `'decryptMsmsgBotMessage: missing meta.target_id'`
    ← malformed stanza — deserves NACK/retry
  - `'decryptMsmsgBotMessage: MessageSecretMessage missing encIv/encPayload'`
    ← malformed proto — deserves NACK/retry
  - real AES-GCM auth-tag mismatch (string varies but may also start
    with `decryptMsmsgBotMessage:` if wrapped)
    ← deserves the Signal retry path

The broader prefix silently ACK'd all of those, hiding real protocol
failures from the server-side retry machinery. Narrow the match to
the exact substring that uniquely identifies the orphan-cache case:

  startsWith('decryptMsmsgBotMessage: no messageSecret for ')

Other `decryptMsmsgBotMessage:` failures now flow normally to the
Signal retry / PDO placeholder-resend path (where they belong).

Comment expanded to document why the narrow match is required.

Validation:
  * build clean
  * 58/58 tests still pass

Thread 12 (P3) — `String(err)` in auth-utils.ts:714 — is cosmetic
and deferred per the audit recommendation.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@rsalcara rsalcara merged commit 285db59 into master Jun 8, 2026
7 checks passed
rsalcara added a commit that referenced this pull request Jun 10, 2026
sync: master → develop 2026-06-08 — backfill release #521 fixes (#523)
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