analyzing-options
Analyzing different approaches for a task or problem with structured comparisons, effort…
Using the transactional-outbox pattern across lib-streaming (writer) and lib-commons/v5/commons/outbox (repository + relay), in two modes. Sweep Mode detects DIY outbox tables, hand-rolled relay loops, send-and-pray emits, missing WithOutboxTx wrapping, and broker calls inside
$ npx -y skills add LerianStudio/ring --skill using-outbox --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/using-outboxContext preview
The summary Claude sees to decide when to auto-load this skill.
Using the transactional-outbox pattern across lib-streaming (writer) and lib-commons/v5/commons/outbox (repository + relay), in two modes. Sweep Mode detects DIY outbox tables, hand-rolled relay loops, send-and-pray emits, missing WithOutboxTx wrapping, and broker calls inside
name: ring:using-outbox description: "Using the transactional-outbox pattern across lib-streaming (writer) and lib-commons/v5/commons/outbox (repository + relay), in two modes. Sweep Mode detects DIY outbox tables, hand-rolled relay loops, send-and-pray emits, missing WithOutboxTx wrapping, and broker calls inside DB transactions. Reference Mode catalogs the writer/repository/envelope API and relay wiring. Go-only. Skip for non-Go or read-only services."
Sweep mode:
Reference mode:
**Parent surface:** ring:using-lib-streaming (full streaming bus) **Repository side:** ring:using-lib-commons (lib-commons/outbox dispatcher, repository, handler registry) **Adjacent:** ring:instrumenting-streaming-events (eventable-point identification → emit wiring), ring:using-runtime (panic-safe relay loops), ring:using-assert (invariant checks on envelope decode)
---
The transactional outbox solves one operational invariant: **business state and the event that announces it must commit atomically, or not at all**. Without it, three failure modes are inevitable in production:
1. **Lost event.** Business state commits, the producer calls `broker.Emit`, the broker is down or the network blips — the event vanishes. The ledger now believes a transaction happened that no downstream consumer ever heard about. 2. **Phantom event.** Producer emits successfully, then the DB commit fails. Downstream consumers now act on a transaction that never happened. 3. **Send-and-pray.** Code paths that emit on a best-effort basis "and we'll log it if it fails" — a polite name for systematic data loss under sustained broker outages.
The outbox pattern fixes this by **writing the event to an `outbox` table inside the same database transaction as the business state**. Commit is atomic: either both rows persist or neither does. A separate process — the **relay** (also called dispatcher or poller) — reads pending outbox rows and publishes them to the broker, marking each row `PUBLISHED` on success. Delivery becomes at-least-once: if the relay crashes between publish and mark, the row stays pending and the next cycle retries. Consumers must be idempotent — that is the cost of at-least-once.
In lib-streaming the producer also uses the outbox as a **circuit-breaker fallback**. When a target's circuit is OPEN, `Emit` writes a route-aware `OutboxEnvelope` instead of attempting the broker call. When the breaker closes, the relay drains the backlog through the *originating target's adapter* — bypassing `Emit` itself, so replays cannot re-enter the circuit and cannot re-enqueue themselves. This is what `OutboxModeFallbackOnCircuitOpen` (the default) buys you: a broker outage degrades to a write-ahead log instead of dropped events.
| Request Shape | Mode | |---|---| | "Sweep / audit / find DIY outbox / send-and-pray" | **Sweep** | | "How does the pattern work?" | **Reference** | | "Which interface do I implement?" | **Reference** | | "How do I wire WithOutboxTx in my repository layer?" | **Reference** | | "What is the OutboxEnvelope wire format?" | **Reference** |
---
Dispatch 6 explorers in **one parallel batch**. Each writes its findings JSON; a synthesizer consolidates.
Phase 1: Outbox surface reconnaissance → outbox-surface.json
Phase 2: Multi-angle DIY sweep → 6 × outbox-sweep-{N}-{angle}.json
Phase 3: Consolidated report → outbox-sweep-report.md + outbox-sweep-tasks.jsonBefore sweeping, determine what the service currently does:
1. Grep for `lib-streaming` and `lib-commons/v5/commons/outbox` imports in `go.mod` / source. 2. Locate broker-publish call sites (any of: `Emit`, `kafka.Produce`, `sqs.SendMessage`, `rabbitmq.Publish`, custom wrappers). 3. Locate DB-transaction boundaries (`db.BeginTx`, `*sql.Tx`, repository transactional helpers). 4. Emit `/tmp/outbox-surface.json`:
{
"uses_lib_streaming": true,
"uses_lib_commons_outbox": true,
"broker_call_sites": [{"file": "...", "line": 0, "kind": "kafka|sqs|rabbitmq|custom"}],
"tx_boundaries": [{"file": "...", "line": 0}],
"has_outbox_table_migration": true,
"has_relay_loop": false
}If `uses_lib_streaming=false` AND `broker_call_sites` is non-empty → flag as high-risk send-and-pray candidate before angle dispatch.
Before emitting any Task call, count the explorers you intend to launch in this turn.
All 6 explorers leave in the SAME TURN, before reading any explorer output.
Forbidden sequences:
If you find yourself about to dispatch an explorer in a turn AFTER any explorer has already returned a result → STOP. You violated parallel dispatch. Report the violation and mark the phase INCOMPLETE rather than completing the trickle.
After the dispatch turn, verify a
Proven engineering practices, enforced through skills. Ring is a comprehensive skills library and workflow system for AI agents that transforms how AI assistants approach software development.
Repo: LerianStudio/ring
Analyzing different approaches for a task or problem with structured comparisons, effort…
Auditing a service's production readiness against Ring engineering standards across base…
Cleaning redundant and obvious comments following clean code principles while preserving…
Commit changes with scope allowlist enforcement, atomic grouping, GPG-signed conventional…
Creating a handoff document that captures session state (completed work, decisions, open…
Creating an isolated git worktree for parallel branch work: selects the directory by priority…