generated from ben/template
2.6 KiB
2.6 KiB
0.1.1 Relay Envelope and Anti-Loop Rules
envelope
from dataclasses import dataclass
from typing import Literal, Optional
Origin = Literal["zulip", "xmpp"]
Direction = Literal["zulip_to_xmpp", "xmpp_to_zulip"]
@dataclass(frozen=True)
class RelayEnvelope:
envelope_id: str
origin: Origin
source_message_id: str
sender_display_name: str
target_mapping: str
timestamp: str
body_text: str
sender_platform_id: Optional[str] = None
raw_direction: Optional[Direction] = None
receipt_time: Optional[str] = None
Required for v0:
| field | purpose |
|---|---|
| origin | source platform |
| source_message_id | duplicate detection |
| sender_display_name | relay attribution |
| target_mapping | fixed bridge route |
| timestamp | event ordering / logs |
relay output
| direction | plain-text shape |
|---|---|
| Zulip -> XMPP | [zulip] <sender>: <body> |
| XMPP -> Zulip | [xmpp] <sender>: <body> |
Optional machine stamp:
- bridge_id
- relayed_from
- relayed_source_id
loop guards
-
self-authored
- Zulip sender == bridge account
- XMPP sender == bridge nick/jid
-
stamped bridge message
- inbound carries this bridge instance stamp
-
recent-seen duplicate
- key = (origin, source_message_id)
Order:
- scope check
- self/stamp check
- duplicate check
- normalize + relay once
- record seen key after success
failure policy
| case | action |
|---|---|
| empty body after normalization | drop + log |
| unknown origin | drop + log |
| unmapped target | drop + log |
| no usable id | synthesize fallback id, log it |
| non-chat event | drop + log |
| duplicate upstream event | drop, info/debug log |
reconnect policy
- no history backfill
- only newly delivered events
- in-memory TTL cache suppresses short replay bursts
- restart may re-emit old events; acceptable for v0
non-goals
- edits / deletes / reactions
- attachment mirroring
- presence / roster sync
- multi-room routing
- Hermes / Retcon integration
exit condition
- envelope shape is frozen
- loop guards are explicit
- duplicate / malformed / reconnect behavior is explicit