Repository navigation
fix(imessage): the SMS pre-route branch skipped the outbound audit log - #228
Merged
Merged
Conversation
Found by the first real end-to-end test after the mute was lifted. A contact
texted "Hi", the bot replied "hey what's up" — the path works — but the audit
log added to make reply quality measurable had NO record of it.
Cause: the reply went out via the SMS pre-route branch (the contact is on RCS,
so iMessage is skipped in favour of Text Message Forwarding). That branch
returns at its own `return { ok: true }`, before the audit line at the end of
send(). Every RCS/SMS-only contact's replies were invisible to it.
This matters more than a missing log line: the whole point of the audit was
that a week of traffic left only ~33 verbatim samples, and the contacts most
likely to be missing from the corpus are exactly the ones on non-iMessage
handsets — a silent, systematic sampling bias in the data meant to answer
"does the bot sound like me".
Audited both early returns now, same field shape as the main site (plus
via:"sms-preroute" so the paths are distinguishable) and a test that asserts
every send path reaches an audit line rather than checking a value.
57/57 imessage-bridge, 1498/1498 bridge-core, typecheck clean.
Contributor
🔎 Codex cross-audit (agent:audit)No Blocking findings. I did not find correctness, security, or missed-edge regressions in the PR diff. The runtime change only adds the missing Verification note: I attempted the targeted Vitest file, but dependencies are not installed in this workspace: |
Same class as the iMessage SMS pre-route gap, found by auditing every send path instead of waiting for the next test to trip over one: sendSelf talks to the Baileys socket DIRECTLY rather than going through sendMessage, so all owner-facing WhatsApp traffic — briefs, digests, draft approvals, drop notices — never reached the audit line. The iMessage bridge logged owner sends (they go through send()); WhatsApp did not. So "how much of what we send is machinery vs real replies" was computed from a corpus missing one channel's owner traffic entirely, which is precisely the ratio the audit exists to answer. Audited with via:"sendSelf" so the paths stay distinguishable. sendMessage's two early returns are deliberately NOT audited — they are suppressions (the abstain sentinel, and the duplicate-send backstop), not sends. 1498/1498 bridge-core, 57/57 imessage-bridge, both bridges typecheck clean.
Contributor
🔷 Gemini cross-audit (agent:audit-gemini)Audit Report: unified diff in
|
Third instance of the same class, found by enumerating every raw
socket.sendMessage call rather than fixing them one test at a time.
confirmToSelf is the owner's MAIN reply channel on WhatsApp and it talks to
the socket directly — so after fixing sendSelf the audit still saw almost no
owner-side WhatsApp traffic.
Audited the full set now. What each remaining raw send is, and why it stays
unaudited:
- sendVoiceToSelf / flushWarnings / checkAttention — owner-facing, and all
of them ultimately duplicate text already audited elsewhere
- sendDocument — a file, not a text reply
- sendReaction — an emoji tapback, not a message
The guarantee that matters: NO contact-facing text reply can reach a contact
without an audit line, on either bridge. Owner traffic is audited wherever it
originates a message rather than echoing one.
1498/1498 bridge-core, 57/57 imessage-bridge, both bridges typecheck clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Found by the first real end-to-end test after the mute was lifted.
A contact texted "Hi", the bot replied "hey what's up" — the path works. But the audit log added in #224 to make reply quality measurable had no record of it.
Cause
The reply went out via the SMS pre-route branch (the contact is on RCS, so iMessage is skipped in favour of Text Message Forwarding). That branch returns at its own
return { ok: true }, before the audit line at the end ofsend().Every RCS/SMS-only contact's replies were invisible to the audit.
Why this matters more than a missing log line
The whole point of the audit was that a week of traffic left only ~33 verbatim samples. The contacts most likely to be missing from the corpus are exactly the ones on non-iMessage handsets — a silent, systematic sampling bias in the data meant to answer "does the bot sound like me?"
Measuring voice against a corpus that structurally excludes a class of contacts would have produced confident, wrong conclusions.
Fix
Both early returns now audit, same field shape as the main site plus
via: "sms-preroute"so the paths stay distinguishable.The test asserts every send path reaches an audit line — an invariant, not a value. That's the bug class: a new
returninsend()silently drops a contact out of the corpus.57/57 imessage-bridge, 1498/1498 bridge-core, typecheck clean.