mgmt: restart-window invite double-processing can auto-DECLINE a legitimate DM invite (#89a cooldown misfire) #97
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
dark/nether-voicebridge#97
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Observed in prod 2026-07-12 04:00 with the first real self-serve user (@dau:tinier.town), seconds after the alpha.24 restart:
Two stacked problems:
invited_rooms()sweep both fire for one invite. The first acceptance stamps the #89a per-sender invite cooldown; the duplicate two seconds later then hits its own stamp and takes the DECLINE path —room.leave()on an invited room REJECTS the invite. Net effect: the user watches their invite get refused by the bot. The cooldown was designed to rate-limit distinct invites from one sender, not to fire on a duplicate of the invite we just accepted.public" — most consistent with the inviter having already retracted/left the invite during our restart window (their third attempt after the #96 docs bug; they'd been getting silence for an hour). Not our bug per se, but it's what left the duplicate-processing path exposed.Fix direction: dedupe invite handling per room (in-flight/handled set keyed by room id — accept-once), and/or only stamp the #89a cooldown after a SUCCESSFUL join, and never take the decline path for a room we're already mid-join on. A failed federated join should also not leave the invite in limbo — either retry with backoff or decline explicitly with a log that says why.
Severity: real users hit this exactly when it hurts most (their retry lands during a deploy restart).
Live escalation notes (2026-07-12, ~04:15–04:45):
mgmt_cooldown_secscommented out (backupconfig.toml.bak-pre-97mitigation) — #89a is inert when unset, so duplicates re-accept harmlessly. RESTORE with this fix. Cost while unset: no command cooldown,reportun-gated.500 M_UNKNOWN: Server returned bad 200 response: Deserialization … missing field event. BOTH servers run Tuwunel 1.8.1, so this is a Tuwunel↔Tuwunel federation invite-join bug (intermittent: 3 joins succeeded earlier tonight). Bridge-side workaround for the stranded user: REVERSED the flow — the bot created the DM on nether.im and invited them (their joins toward nether.im work). Candidate upstream Tuwunel report; evidence in prod journal 04:37.create_dm/createRoom room has ONE joined member until the invitee accepts; the 5-min maintenance sweep reaps ≤1-member non-safe rooms → the invite gets retracted if the human takes >5 min to accept. This also affects #94'smsg/announceto owners without an existing DM. Fix alongside the dedupe: exempt rooms with a PENDING invite (or younger than some grace) from the #89b reap.Shipped in v0.3.0-beta.1, deployed to prod 2026-07-12 07:29 UTC. #97: invite dedupe + cooldown-stamp-after-join (alpha.25) + the server-side pending-invite reap gate (beta.1; the alpha.25 summary-count gate was proven lagging by the #99 drill — evidence on #100). Prod
mgmt_cooldown_secsrestored with the deploy; post-restart journal confirms failed joins no longer arm the cooldown. #103: both room-id generations accepted (link/ban/report), via hints on first-contact joins, shape rejections logged. Residual mode 2 tracked as #104 with a live known-fail scenario.