Repository navigation
Unify trigger retries onto the connection-delivery outbox (do not build a second mechanism) #17
Description
Re-scoped 2026-08-04
Migration 0058 gave connections an at-least-once delivery outbox: write-before-attempt, exponential backoff (~1m/5m/15m/1h/3h, max 5 attempts), dead-lettering, idempotency on (connection, emitting run, payload-hash), replay, and trace correlation. See lib/connection-deliveries.ts.
Triggers still have none. lib/triggers.ts contains no retry path at all — a failed cron/webhook trigger is simply lost.
That is worse than the original state of this ticket: the platform now has two failure routes with different reliability guarantees, which is a trap for anyone reasoning about whether their automation is durable. The answer is "it depends which edge fired," and nothing in the UI says which.
So this ticket is no longer "add a retry policy to triggers." It is: make triggers reuse the delivery outbox rather than growing a parallel mechanism with its own semantics, its own backoff table, and its own dead-letter concept.
Scope
- Generalize the outbox from connection-delivery to a generic durable-attempt record (source = connection | trigger), or have trigger runs enqueue through the same table.
- Triggers inherit backoff, max attempts, dead-lettering, idempotency, and replay unchanged.
runDueTriggersandrunDueDeliveriesconverge onto one due-work sweep on the per-minute cron.- Cron triggers still advance
next_run_atsafely and never hot-loop on failure. - Notification on repeated failure (the part of the original scope that stands).
Acceptance
- A failing cron/webhook trigger retries with the same policy a connection delivery gets.
- Exhausted attempts leave one terminal, visible, replayable state — the same one connections use.
- No duplicate imports/tasks on retry (idempotency carries over).
- A user cannot observe different durability depending on whether work arrived via a trigger or a connection.
- Tests cover success-after-retry, exhausted retries, no-hot-loop, and notification.
Console surface for this: #19 (triggers) and #182 (connections).
Original ticket
Summary
Add retry/backoff behavior and user-visible failure notifications for webhook, cron, and connector sync triggers.
Why
Trigger runs currently record success/failure and increment failure counts, but failed work requires the user to inspect events manually. Production automation needs controlled retries and clear notification when a trigger is broken.
Scope
- Add retry policy fields to trigger config or table: max attempts; backoff strategy or next retry time; notify on first failure / repeated failures
- Add retry event statuses to
agent_trigger_events. - Avoid hot loops and duplicate imports/tasks.
- Send notifications through existing platform notification/push surfaces where available.
- Add console visibility for failure state and retry schedule.
Activity
[-]Trigger retry policy, backoff, and failure notifications[/-][+]Unify trigger retries onto the connection-delivery outbox (do not build a second mechanism)[/+]feat(triggers): failed triggers reuse the delivery outbox (#17)
serge-ivo commentedon Aug 4, 2026
Closed by
a1946a6(migration 0064).Triggers now reuse the connection outbox rather than growing a second mechanism, which was the re-scoped ask.
dispatchTriggerenqueues on failure only — the happy path keeps its extra write, and the vast majority of dispatches succeed.attemptDeliveryalready built a synthetic trigger row, so the retry mechanics needed no change at all. What it lacked was labelling: a stuck trigger and a stuck connection are the same mechanism but not the same problem, so failures are now logged under the producing edge and are distinguishable in the trace.Migration 0064 adds
sourcewith a'connection'default, so every existing row and caller is unchanged and there is no data migration.connection_idbecomes the generic producing-edge id and keeps its name — renaming would touch every query and index for a cosmetic gain, and SQLite rewrites the table to do it.Per-trigger accounting (
failure_count,last_error) is untouched: the outbox is additional durability, not a replacement for what the console already shows.4 tests, including one asserting the happy path writes nothing to the outbox.
serge-ivo commentedon Aug 4, 2026
Done in
a1946a6(migration 0064). Triggers reuse the connection outbox rather than growing a second mechanism; retry mechanics needed no change, only labelling so a stuck trigger is distinguishable from a stuck connection.feat(console): the pump's failures are the part you need to see (#182)