Back to blog

Dev Diary #20

Killed duplicate-dispatch bugs in two services by replacing crude cooldowns with idempotent acks and proper redeliver...

May 18, 2026

Dev Diary #20

The flashcastr webhook started double-firing replies whenever the inbound payload arrived twice, which it does, often. The 6h per-author cooldown I'd written as a crude rate limiter was the wrong shape — it punished legitimate back-and-forth and did nothing to stop duplicate dispatches from the same payload. Ripped it out, replaced with an inbound rate limit keyed on the mention itself, plus a seen-ack LIKE on the cast so the webhook layer has an idempotent signal before `conversational-reply` ever runs. The threading was wrong too: replies were posting as top-level casts instead of actual Farcaster replies, which made the bot look like it was shouting into the void rather than talking to anyone. Two migrations landed alongside — `0009_add_mentions`, `0010_add_corrections` — because the self-correction path needs durable state, not in-memory hope. Over in agent-blog the publish handlers were not idempotent under RabbitMQ redelivery. Same class of bug, different surface: a retry would re-publish, and I'd find out via duplicate output. Fixed with a dedupe check before the side effect, tests in `publish-handlers.spec` covering the redelivery case explicitly. The dotfiles churn was mostly housekeeping that piled up: `g checkout` now `cd`s into the right worktree when the branch lives elsewhere, `wt` mandates a monitor pane for every lane so I stop losing track of background work, and the `grid-4x2` tmux script was only re-tiling the first split in the loop — classic off-by-one, embarrassing once spotted. Also scrubbed PII and org references across the tree before I forgot which files still had them. Universal Limbs got a from-scratch site wired into Sanity so the founder can edit copy without me. Vercel deploy config, OG images, real socials. The Sanity embed inside a React app is a bit awkward — the studio route sits next to the public pages and the auth boundary is fuzzier than I'd like. Still open: the seen-ack LIKE relies on Neynar webhook ordering I haven't fully stress-tested, and the correction-intent flow can probably be tricked by a malicious reply chain. Need to write adversarial fixtures next.

Home
About
Resume
Projects
Blog
Press
Search