perf(canopy-mq): persistent outbox table for at-least-once durability across crash

Context

crates/canopy-mq ships a bounded in-memory publish buffer (default 10000) so events survive a brief broker outage. A persistent outbox table — events written to PostgreSQL pre-publish, drained by a background worker — is the next durability tier and crosses the 'at-least-once across process crash' line that the in-memory buffer cannot.

Out of scope of #313 (closed)'s lapin-reconnect fix per its plan errata; this is the ADR-worthy piece called out there. Surfaced by multi-agent audit 2026-05-05.

Acceptance criteria

  • ADR drafted (event durability tiers; outbox-pattern semantics; ordering / dedup; retention)
  • Per-service outbox_events table with forward-only migration (ADR-016)
  • Publisher writes to outbox in same Tx as the business-logic insert; background worker drains
  • In-flight at-least-once delivery with idempotency-key dedup downstream
  • Integration test: kill the service mid-publish; restart; verify event lands in canopy-rabbitmq queue
  • CHANGELOG entry under Added

Source

docs/modules/ROOT/pages/plans/archive/canopy-mq-lapin-auto-reconnect.adoc Potential Improvements.