fix(email-ingress): enqueue message.posted for LC-75 subscribers (LC-205) #268
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/lc-205-email-ingress-message-posted"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
finalize_email_inbox_message_send(LC-77 per-room email ingress) never enqueued themessage.postedoutgoing-webhook event. So every LC-75 outgoing-webhook subscriber — including the bridge daemons LC-78 builds toward — silently missed every email-ingress message: no error, no log, no signal. Theoutgoing_actoremail_inboxarm was already wired but unreachable because the enqueue call was never added at this path.~11-line fix: add the enqueue, mirroring the webhook path exactly.
Verification (done before the fix)
Read all four finalize paths first. The three working ones agree on all axes, so the email path is an unambiguous missing sibling:
finalize_message_send(web)userbroadcast_room_messagefinalize_webhook_message_send(LC-74)webhookfinalize_bridge_message_send(LC-78)bridgefinalize_email_inbox_message_sendNo inconsistency between the working paths — nothing to file separately. The email path is the closest sibling to webhook (empty
user_id, synthetic actor, non-DM only, identical mention-reconcile structure), so the fix mirrors webhook verbatim, differing only in theoutgoing_actorarm.Cross-checked
outgoing_actor's signature before commit:(user_id, webhook_id, email_inbox_id, bridge_id, bridge_foreign_name)—email_inbox_idis the 3rd slot, sooutgoing_actor("", None, Some(email_inbox_id), None, None)hits theemail_inboxarm.The fix
In
finalize_email_inbox_message_send, immediately afterbroadcast_room_message(exactly where webhook's enqueue sits relative to its broadcast):Tests (
outgoing_webhook_email_ingress.rs, mirrors LC-78outgoing_webhook_actor_payload)Two independent tests (split positive/negative for sharp diagnosis):
email_ingress_post_fires_message_posted_with_email_inbox_actor— drives the real post path (email_ingress::actor::post_email_message), reads the enqueued delivery row, asserts:event == "message.posted",actor.kind == "email_inbox"ANDactor.email_inbox_id == inbox_id(specific variant + id, notis_some()),bodymatches,room_idmatches.non_email_post_in_same_room_uses_user_actor_not_email_inbox— anti-over-fire guard: a normal user post in the same room yieldsactor.kind == "user", proving the email-inbox actor is selected by the path, not blanket-stamped on everymessage.posted.Docs
docs/protocol-bridges.md: removed the "Email-ingress does not fire LC-75 outgoing webhooks" Known-gaps bullet (closed) and dropped the conditional caveat on the email-ingress actor-shape line.Out of scope (confirmed)
No other finalize path is missing the enqueue (only email) → no grep-ban enforcement (N=1 isn't a pattern; revisit only if a third offender appears). No
outgoing_actorrefactor. No broader email-ingress flow expansion (covered by LC-77 tests).Test plan
cargo check --testsclean, standalone + saas.outgoing_webhook_actor_payload,outgoing_webhooks,email_ingress_process) all green.just test(--no-fail-fast): 125 binaries, only the pre-existinglc77_webhook_render_fixturefailures (4 tests, confirmed failing on cleanmain— drifted golden fixtures, unrelated to this change, filed separately).Pre-existing finding (unchanged by this PR, still open)
lc77_webhook_render_fixture's 4 golden-fixture tests fail on cleanmain— rendered HTML diverged from committed fixtures. NeedsFIXTURE_WRITE=1regeneration under its own ticket. Not touched here.