fix(hooks): store a hook delivered twice only once

A doubled hook registration (plugin + leftover checkout install) POSTs every
event twice with a byte-identical payload, so the timeline showed each row
twice and token/alert/lane side effects ran twice. POST /api/hooks/event now
skips a payload identical to the session's LATEST event from the last 10s
(findRecentDuplicateEvent). Latest-only keeps two legitimately identical
Stop events of consecutive turns, which always have other events between.
This commit is contained in:
2026-09-23 09:18:17 +07:00
parent 1b561c22d9
commit 92cee94431
6 changed files with 66 additions and 8 deletions
+14
View File
@@ -1144,6 +1144,20 @@ router.post("/event", (req, res) => {
});
}
// The same hook delivered twice — AgentHub's hooks registered twice (plugin
// + a leftover checkout install, two marketplaces), or two servers on one DB
// that both got the POST — carries a byte-identical payload. Store it once,
// and skip the lane/alert side effects too, or every timeline row, status
// flip and alert doubles.
// ponytail: DB lookup, so two servers committing the same hook in the same
// instant can still both win; a unique payload-hash column closes that.
if (
data.session_id &&
stmts.findRecentDuplicateEvent.get(data.session_id, hook_type, JSON.stringify(data))
) {
return res.json({ ok: true, duplicate: true });
}
const result = processEvent(hook_type, data);
if (!result) {
return res.status(400).json({