This repository was archived by the owner on Jul 16, 2026. It is now read-only.
Repository navigation
feat(discord-bridge): record outbox audit on every delivery (Phase 5.16) - #84
Merged
Merged
Conversation
Phase 5.15 added the dashboard reader + Outbox card. Slack writes were already populating outbox_log, so slack deliveries became visible right away. Discord deliveries still didn't, because discord-bridge.py had no `outbox_log.append(...)` calls. Ported the three OSS sites that cover discord's main delivery paths. Sites ported (each `try/import outbox_log/append/except Exception: pass` to keep telemetry fail-open and non-load-bearing): 1. `poll_results` reply path — every channel.send() reply (DM or guild channel). channel_type derived from `discord.DMChannel` check; recipient_label = "<recipient> DM" or "#<channel-name>". 2. Proactive owner-DM path — every dm.send() proactive notification. channel_type="discord_dm"; recipient = owner_id; recipient_label from fetched user.name. 3. dm-fallback channel-redirect path — every target_channel.send() when a [channel: <id>] marker routes a result to a non-originating channel. channel_type="discord_channel"; recipient = the resolved target_channel_id (NOT the owner_id), so the dashboard reflects where the message actually landed. Two stando-specific send sites were NOT ported and don't have OSS equivalents: - L2225 welcome message to new guild user (stando-only feature) - L2705 cap-hit reply for cloud-cap accounting (stando-only) Adding outbox writes for those would be a feature addition, not a port — out of scope for the minimal-divergence sync. Tests (new tests/discord-bridge-outbox.test.py, 5 cases): - Structural: exactly 3 append sites, each wrapped in `try/import outbox_log/append/except Exception: pass`. - Variable binding: each append carries channel_type, recipient, recipient_label, body, task_id. - Channel-type vocabulary stays in dashboard._channel_icon's known set (catches typos that would silently render the default → arrow). - Round-trip: writes via outbox_log are read back via the dashboard reader added in Phase 5.15. - Drift guard: every append is preceded by a _chunk_for_discord send loop within 30 lines (prevents future PR from recording empty-body audit rows when the bridge only sent files). Verification: - 58/58 Python tests pass (was 57; +1 net-new file). - TypeScript typecheck clean. - `python3 -m py_compile src/discord-bridge.py` clean. Phase 5.16 of the OSS → private sync. Discord deliveries now show up alongside slack in the dashboard Outbox card. Co-authored-by: Cursor <cursoragent@cursor.com>
This was referenced Jun 2, 2026
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Summary
Phase 5.15 added the dashboard reader + Outbox card. Slack writes were already populating
outbox_log, so slack deliveries became visible right away. Discord deliveries still didn't, becausediscord-bridge.pyhad nooutbox_log.append(...)calls. Ported the three OSS sites that cover Discord's main delivery paths.Sites ported
Each wrapped in
try / import outbox_log / append(...) / except Exception: passso the audit log can NEVER block a Discord delivery (telemetry must not be load-bearing).channel_typerecipientpoll_resultsreply (DM or guild channel)discord_dm|discord_channel(fromisinstance(channel, discord.DMChannel))str(channel.id)discord_dmstr(owner_id)dm-fallback channel-redirect(when[channel: <id>]marker routes a result elsewhere)discord_channelstr(target_channel_id)(not owner_id — reflects where the message actually landed)recipient_labelset everywhere for human readability in the dashboard card (otherwise it falls back to the bare channel id which is useless for review).Out of scope
Two stando-specific send sites were NOT ported and don't have OSS equivalents:
Adding outbox writes for those would be a feature addition, not a port — out of scope for the minimal-divergence sync rule.
Tests
New
tests/discord-bridge-outbox.test.py(5 cases)try / import outbox_log / append / except Exception: pass. Future PR that adds an unwrapped 4th site fails this.channel_type,recipient,recipient_label,body,task_id.dashboard._channel_icon's known set (catches typos that would silently render the default→arrow).outbox_logare read back via the dashboard reader added in Phase 5.15._chunk_for_discordsend loop within 30 lines (prevents future PR from recording empty-body audit rows when the bridge only sent files).Test plan
python3 tests/discord-bridge-outbox.test.py→ 5/5pnpm -s typecheck→ cleanpython3 -m py_compile src/discord-bridge.py→ cleanResult
After this merges, Discord DM replies, channel replies, proactive notifications, and channel-redirected results all show up in the dashboard's Outbox card alongside slack — symmetric audit visibility across both major bridges.
Roadmap
The bridge → outbox → dashboard pipeline is now feature-complete across slack + discord. Possible next phases (none currently flagged high-confidence):
dm-result.pyfor outbox writes (REST fallback path; would complete coverage when the live bridge is offline).Made with Cursor