When WriteBatchAsync returned a wrong-cardinality outcome list, DrainOnceAsync
threw InvalidOperationException after potential delivery — causing duplicate
events on re-drain or permanent queue stall on a deterministic writer bug.
- The throw replaced with log + backoff: mismatch is recorded into _lastError,
_drainState set to BackingOff, backoff bumped, method returns without applying
any outcomes, mirroring the writer-exception path.
- Regression test Writer_returning_wrong_cardinality_outcomes_sets_backing_off_and_keeps_rows
asserts rows stay queued, DrainState = BackingOff, LastError populated, and
that a fixed writer subsequently drains cleanly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>