KB-634F

IU Core Event Worker — 03 Worker architecture

5 min read Revision 1
dieu44iu-core-mvpevent-workerarchitecturecursordead-letterv0.62026-05-21

IU Core Event Worker — 03 Worker architecture

The problem

event_outbox is a shared append-only log (93k+ rows, mostly system/alert). It has no delivery-state columns — no delivered_at, no processed_at. It is not a work queue. A consumer therefore cannot mark rows; it must track its own position.

Design

The worker is a SQL function, not a daemon — invoked, transaction-scoped, atomic. No process, no cron, no container is created by this package (invocation is a separate operator/DOT decision). The Python module cutter_agent/iu_core/route_worker.py is a pure DB-free mirror of the decision contract.

Substrate — migration 008

  • iu_route_worker_cursor — one row per named worker. Keyset high-water mark (last_created_at, last_event_id) over the iu-domain event_outbox stream. event_domain scope, run counters, last_run_summary.
  • iu_route_dead_letter — an iu event the worker could not route/deliver. Full event_snapshot so it is replayable without re-reading event_outbox. idempotency_key UNIQUE; resolved via resolved_at+resolution, never DELETEd. The dead-letter table is the worker's retry queue.

iu_route_attempt (migration 002) is reused unchanged as the per-event audit sink — it already has event_ref uuid, route_kind, status, idempotency_key, UNIQUE (idempotency_key, attempt_no).

Worker function — migration 009

fn_iu_route_worker_run(p_worker_name, p_batch_limit) — one transactional pass:

  1. Dual fail-closed gatefn_iu_core_routes_enabled() (master) AND fn_iu_route_worker_enabled() (dedicated worker kill-switch, dot_config 'iu_core.route_worker_enabled'). Either closed → clean no-op.
  2. Claim — keyset batch WHERE event_domain='iu' AND (created_at,id) > cursor ORDER BY created_at,id LIMIT n FOR UPDATE OF eo SKIP LOCKED. SKIP LOCKED gives safe multi-worker concurrency.
  3. Route — resolve iu_outbound_route by (domain,type,stream).
  4. Decide + audit — per event, write exactly one iu_route_attempt: dry_run (route enabled+dry_run — logs a decision, delivers nothing) / disabled / skipped (no route) / failed.
  5. Dead-letter — a per-event EXCEPTION block: one bad event cannot abort the batch; the failure is recorded as a failed attempt and snapshotted into iu_route_dead_letter.
  6. Advance cursor — atomically with the attempt writes (same txn).

Idempotency — no duplicate delivery

Deterministic key iu_wrk:{worker}:{route}:{event_id}. Two layers:

  • Cursor — a re-run reads nothing already passed.
  • Key — even if the cursor is reset, ON CONFLICT (idempotency_key, attempt_no) DO NOTHING writes no duplicate attempt.

Delivery seam — fail-closed

fn_iu_route_deliver is the dry_run=false delivery point. It is intentionally unbuilt — it RAISEs feature_not_supported. The worker catches it and dead-letters the event. No downstream delivery is possible from this package, by construction. Building the seam is the dry_run=false macro (doc 08).

Recovery

fn_iu_route_dead_letter_replay(id) re-attempts one dead-lettered event as a fresh iu_route_attempt (attempt_no incremented); resolves the row on a dry_run/sent outcome.

Files

File Role
sql/iu-core/008_route_worker_substrate.sql cursor + dead-letter tables
sql/iu-core/009_route_worker_functions.sql 5 functions + 3 views
sql/iu-core/runtime/060_route_worker_activate.sql worker gate false + cursor seed
sql/iu-core/runtime/070_route_worker_verification.sql read-only verify W1–W9
sql/iu-core/runtime/080_route_worker_disable.sql disable runbook
cutter_agent/iu_core/route_worker.py pure decision-contract mirror

Known limitation (for doc 08)

The keyset cursor advances monotonically. A row committed late with an earlier created_at (a long-running unit_version txn) could be skipped. Acceptable for a dry-run MVP; a dry_run=false delivery worker needs a safety-lag / high-water-mark.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/v0.6-iu-core-event-worker-structure-ops-autocut-integration-open-goal/03-worker-architecture.md