kcode-kennedy-stepped-turn-runtime 0.1.1

Watermark-bounded mailbox sequencing and stepped-turn session driving
Documentation
# Public API

```rust
pub use kcode_kennedy_sessions::PendingTurnAdmission;

pub struct QueuedAdmission<D> {
    pub key: String,
    pub recorded_at: String,
    pub admission: PendingTurnAdmission,
    pub delivery: D,
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum PushResult {
    Queued { sequence: u64 },
    Duplicate { sequence: u64 },
}

pub struct ProcessedAdmission<D> {
    pub key: String,
    pub delivery: D,
    pub accepted: bool,
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ControlSignal { Stop, Deadline }

pub enum TurnExit<D> {
    Complete { answer: Option<String>, processed: Vec<ProcessedAdmission<D>> },
    Interrupted { signal: ControlSignal, processed: Vec<ProcessedAdmission<D>> },
}

pub struct DriveFailure<D> {
    pub error: anyhow::Error,
    pub processed: Vec<ProcessedAdmission<D>>,
}

impl<D> std::fmt::Debug for DriveFailure<D>;
impl<D> std::fmt::Display for DriveFailure<D>;
impl<D> std::error::Error for DriveFailure<D>;

pub struct Mailbox<D> { /* private fields */ }

impl<D> Mailbox<D> {
    pub fn new() -> Self;
    pub fn sender(&self) -> MailboxSender<D>;
    pub fn is_empty(&self) -> bool;
    pub async fn notified(&self);
}

impl<D> Default for Mailbox<D>;

pub struct MailboxSender<D> { /* private fields */ }
impl<D> Clone for MailboxSender<D>;
impl<D> MailboxSender<D> {
    pub fn push(&self, item: QueuedAdmission<D>) -> PushResult;
}

pub async fn drive_pending_turn<D, C, F, S, K>(
    session: &mut kcode_kennedy_sessions::Session,
    operation_id: uuid::Uuid,
    turn_deadline: Option<kcode_kennedy_sessions::TurnDeadline>,
    mailbox: &mut Mailbox<D>,
    control: S,
    checkpoint: C,
    cancel: K,
) -> Result<TurnExit<D>, DriveFailure<D>>
where
    D: Send,
    C: FnMut(serde_json::Value) -> F + Send,
    F: std::future::Future<Output = anyhow::Result<()>> + Send,
    S: std::future::Future<Output = ControlSignal> + Send,
    K: FnMut(ControlSignal);
```

A mailbox is an unbounded in-memory FIFO with one consumer, enforced by `drive_pending_turn` taking `&mut Mailbox<D>`. Cloneable senders may push concurrently. Locks cover only short in-memory transitions and are never held across an await.

Each newly queued entry receives a strictly increasing sequence beginning at 1; exhaustion panics. Keys deduplicate across both queued and privately drained entries. A duplicate returns the original sequence and drops the supplied item. A key becomes reusable only after successful admission and checkpointing are acknowledged.

At each `Yield`, the driver captures a finite sequence watermark and privately drains FIFO entries through it; later arrivals wait for another yield. An admission error restores the current and all later privately drained entries to the queue in original FIFO order before returning, and that drive call does not retry them. After successfully processing the watermark, the turn advances exactly once.

Successful admission includes successful checkpointing before acknowledgement and inclusion in `processed`. An empty `User` admission is acknowledged and reported with `accepted: false`. Every ordinary returned `DriveFailure` carries all earlier accepted, checkpointed, and acknowledged entries in `processed`; panic and internal invariant corruption are excluded from this guarantee.

`is_empty` observes only queued entries. `notified` is advisory and notifications may coalesce, so callers must recheck state after waking.

Session and checkpoint work is serial and reaches the next arbitration point. Control is biased only while awaiting the provider. On control, `cancel(signal)` runs before aborting and joining the waiter; the normal result is `Interrupted`, but a non-cancellation task join error is a `DriveFailure`. Mailbox arrivals do not abort provider work.

The caller owns interruption and deadline mutation, persistence, reconstruction, transport acknowledgement, and delivery of returned `delivery` values.