Adds RingBufferFallback — an in-memory drop-oldest ring buffer used by the upcoming FallbackAuditWriter (Bundle B-T4) when the primary SQLite writer is throwing. Backed by Channel<AuditEvent> with BoundedChannelFullMode.DropOldest, fixed capacity (default 1024). Channel.CreateBounded(DropOldest) does NOT natively signal a drop on TryWrite, so overflow is detected by comparing Reader.Count before and after the enqueue: when the buffer is already at capacity and a new TryWrite succeeds while keeping the count at capacity, exactly one event was displaced and RingBufferOverflowed is raised (one event per drop). Public surface: - bool TryEnqueue(AuditEvent) — always succeeds unless completed. - IAsyncEnumerable<AuditEvent> DrainAsync(CancellationToken) — FIFO. - void Complete() — closes the channel so DrainAsync can finish. - event Action? RingBufferOverflowed — health counter hook. Tests (3 new, total 23 -> 26): - Enqueue_1025_Into_1024Cap_Ring_DropsOldest_AndRaisesOverflowOnce - DrainAsync_Yields_FIFO_Then_Completes_When_Empty - TryEnqueue_AllSucceeds_ReturnsTrue
2.7 KiB
2.7 KiB