# Public API
```rust
pub use kcode_k1_chat_codex_codec::{BoxValue, Call};
pub use kcode_k1_chat_state::{ActionId, ChatBox};
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Arrival {
System(String), User(String), Attachment,
Return {
action_id: ActionId,
result: Result<String, String>,
},
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Start {
pub job: u64,
pub boxes: Vec<BoxValue>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Launch {
pub action_id: ActionId,
pub result: Result<String, String>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum Status {
Running, Quiet,
Stalled {
message: String,
restartable: bool,
},
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum RestartError {
NotStalled,
NotRestartable,
}
pub struct ConversationState { /* private fields */ }
impl ConversationState {
pub fn new(session: [u8; 12]) -> Self;
pub fn boxes(&self) -> &[ChatBox];
pub fn status(&self) -> Status;
pub fn accept(&mut self, arrival: Arrival) -> Result<(), String>;
pub fn begin(&mut self) -> Result<Option<Start>, String>;
pub fn launch(&mut self, job: u64, call: Call) -> Result<Launch, String>;
pub fn complete(&mut self, job: u64, output: kcode_k1_codex_adapter::ShimOutput<BoxValue>) -> Result<(), String>;
pub fn fail(&mut self, job: u64, message: String, restartable_before_launch: bool);
pub fn restart(&mut self) -> Result<(), RestartError>;
}
```
`begin` submits only boxes not previously submitted, including the newly opened empty Kennedy box. Arrivals accepted while a round runs coalesce FIFO for its next `Start`.
`launch` records and immediately launches one call; its result re-enters through `Arrival::Return`. Calls alone create no continuation.
A requested pre-launch failure is restartable and `restart` reseeds the complete conversation. Completion defects and post-launch failures stall nonrestartably while preserving committed calls and returns.
Each operation is linear in its processed boxes, output, calls, arrivals, and payload bytes, plus synchronous action-launch time.