# T10.3 — Idempotent run admission | Field | Value | |---|---| | Phase | P10 — Orchestration | | Size | S — under 1 day | | Status | Not started | | Flags | — | | Spec | inlined below | | Blocks | T10.4, T10.7 | ## Goal `dispatch_key` on spawn requests: a redelivered spawn request (from Kafka at-least-once delivery, T10.7) becomes a no-op insert instead of a duplicate run. ## Facts (inlined — no spec read needed) - Same principle as the outbox's `(BranchKey, Lsn)` fold-key idempotency (T7.4) — exactly-once is achieved at the admission boundary, not in transport. - `dispatch_key` is caller-supplied, opaque, unique per intended spawn — e.g. a `Reconciler` decision id. - Admission with no `dispatch_key` behaves exactly as today. This is additive, not a required field. ## Steps 1. Add optional `dispatch_key: Option` to spawn-run input. 2. Add a unique index on `(TenantId, dispatch_key)` where `dispatch_key` is set. 3. On spawn: if `dispatch_key` is set and already seen, return the existing `RunId` instead of creating a new run — no error, no duplicate. 4. Test redelivery: same `dispatch_key` submitted twice, concurrently and sequentially. ## Acceptance - Two spawn calls with the same `dispatch_key` produce exactly one run; the second call returns the first run's `RunId`. - Spawn calls with no `dispatch_key` are unaffected. ## Verify **Harness:** spawn endpoint (T10.4) or direct kernel call, two concurrent callers. **Integration test** — `tests/it_idempotent_admission.rs`: 1. Spawn with `dispatch_key=K`; assert one run created, `RunId=R`. 2. Spawn again with `dispatch_key=K`; assert no new run created, returned `RunId == R`. 3. Fire 20 concurrent spawn calls with the same `dispatch_key`; assert exactly one run exists after all resolve. 4. Spawn with no `dispatch_key` twice; assert two distinct runs (unaffected baseline). **Command:** `cargo test -p kernel idempotent_admission -- --test-threads=1` **False pass:** - Testing only sequential redelivery. Concurrent redelivery is the actual failure mode under Kafka rebalance/retry and needs the unique-index race caught, not a check-then-insert race. ## Traps - Making `dispatch_key` required. Breaks every direct/manual spawn call that isn't part of a goal chain. - Deduping by a hash of `(workflow_ref, input)` instead of the caller-supplied key. Two legitimately identical requests would then silently collapse into one run. --- Background (not required to do this task): [rust-agentic-sys.md](../rust-agentic-sys.md) §8.3, §9.3 · [T7.4-outbox-relay.md](T7.4-outbox-relay.md) · [T3.6-version-pinning-at-spawn.md](T3.6-version-pinning-at-spawn.md)