# 03 — 完成 Outbox 到 Asynq 的至少一次投递闭环

**What to build:** 多个 Relay 实例可以并发领取到期 Outbox 事件，并通过有期限租约把公共事件信封可靠投递到 Asynq。瞬时失败会退避重试，进程崩溃后过期租约可恢复；入队成功但数据库标记前崩溃时允许重复投递，但始终传播原事件 ID 和关联标识。

**Blocked by:** 02 — 在业务事务中可靠写入公共 Outbox

**Status:** completed

**架构通道:** Infrastructure。

**完整业务边界:** 本票收口 Relay 的领取、租约、续租、投递、完成、失败、退避与恢复闭环，并通过公开 Asynq Handler 验证结构化信封。明确不实现业务消费者副作用，不承诺精确一次，不迁移未触碰的旧队列生产者。

- [x] Relay 以小批量条件领取或跳锁方式取得处理权，领取、续租、完成和失败均校验当前状态与租约所有者。
- [x] Relay 调用统一队列客户端时传 struct 或 map；传入 `[]byte` 被明确拒绝并有回归测试防止二次序列化为 Base64。
- [x] 入队成功后事件标记为已投递；模拟入队成功但标记前崩溃时，恢复投递仍使用原事件 ID、载荷和关联标识。
- [x] 瞬时失败按有上限的指数退避安排下次领取，达到最大重试或永久失败时保留记录并产生中文安全告警。
- [x] 多 Relay 并发时同一时刻只有租约所有者能够完成事件；Worker 崩溃后其他实例可在租约过期后恢复领取。
- [x] 真实 PostgreSQL、Redis 和 Asynq 链路测试覆盖事务写入、Relay、公开 Handler 与可观察消费结果，不依赖 Relay 私有函数断言。
