#998

Make Mesh Lab receive hooks tolerate device clock skew

Opencallebtcwants to merge intofrom

Summary

The debug-only Mesh Lab receive hooks dm_recv and msg_recv accepted only messages whose timestamp (the sender's clock) was >= the receiver's clock when the command started. If the receiver's clock runs ahead of the sender's, a message that really arrived gets skipped and the command times out.

This showed up on two physical phones whose clocks were about 140 s apart: dm, session_recovery and identity_reset failed on both a feature branch and its base commit, even though the sender got delivery ACKs.

Change

  • New debug-only ArrivedMessageMatcher: when a receive command starts, it records the IDs of messages already in the store and then matches only IDs it hasn't seen. Sender timestamps are never compared with the local clock. The peer / contains / channel filters still apply.
  • dm_recv and msg_recv use it in both TestHookDriver (phone) and WearTestHookDriver (watch, which mirrors the debug helper the same way PttTestAudioAnalyzer is mirrored).
  • file_recv already uses local file modification times, so it is unchanged. ptt_recv has no timestamp filter, so it is also unchanged (see below).
  • Everything stays in app/src/debug/ and wear/src/debug/. No release sources or mesh_lab.py changes.

Risk

Low. Only debug test hooks change, and nothing in the release APK is affected. The one change in behavior: an existing message that gets updated in place (same ID) no longer counts as a new arrival, which is what the hooks are meant to do.

Tests

  • ./gradlew testDebugUnitTest lintDebug :app:assembleDebug :wear:assembleDebug passes.
  • New ArrivedMessageMatcherTest: a message stamped 140 s behind the receiver's clock still matches, a message already present at start is ignored even if its timestamp is ahead, and the filters still apply.
  • Mesh Lab scenario all on two physical phones with one clock about 140 s ahead: 11/12 pass, including dm, session_recovery and identity_reset, which failed before this change. Raw evidence and logs are kept local.

Known remaining failure: ptt_broadcast (separate cause, not a hook bug)

ptt_broadcast still fails when clocks are skewed. The receiver never sees the burst because MessageHandler.handlePublicVoiceFrame drops public voice frames whose packet timestamp is more than ±30 s from the local clock, and it does so without logging. DM PTT goes through Noise without that window, which is why ptt_dm passes. That freshness window is product/protocol behavior, so this PR leaves it alone. Whether to widen it, align it with iOS, or log the drops should be decided separately. With synced clocks, ptt_broadcast is not affected.

Activity

1
chatgpt-codex-connector[bot]6d ago

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

ReviewStatusCommitReview trigger
📝 Code Review✅ Completed 2026-10-24T23:56:44.670801Z0c0b16cPR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.