# kcode-k1-codex-adapter
Version 0.3.0 is a compatibility facade over the published `kcode-k1-codex-runtime` 0.1.0 and `kcode-k1-codex-shim` 0.1.0 crates.
It contains no transport, conversation, shim, or test implementation of its own.
## Public facade
The runtime names `Adapter`, `Turn`, `Config`, `DynamicTool`, `Error`, `ErrorKind`, `Event`, `ToolCall`, and `ToolResult` are direct reexports from `kcode-k1-codex-runtime`.
The shim names `ASYNC_TOOL_ACKNOWLEDGEMENT`, `ToolLaunchFuture`, `ToolCallLauncher`, `BoxCodec`, `ShimItem`, `ShimOutput`, and `Shim` are direct reexports from `kcode-k1-codex-shim`.
Direct reexports preserve the established facade names and signatures while making the concrete crates the sole implementation owners.
Existing source using those names through `kcode_k1_codex_adapter` remains compatible, subject to the documented behavior of the concrete 0.1.0 crates.
`Adapter::close_conversation(key)` is the additive runtime close API.
`Shim::close_conversation()` is the additive per-shim close API.
## Runtime lifecycle
`Adapter::open` starts and initializes one shared long-lived Codex app-server; cloned adapters multiplex opaque conversation keys over that process and persistent native threads.
The same key is sequential: an overlapping turn or close is rejected as busy. Distinct keys may progress concurrently.
`Adapter::close_conversation` is idle-only and idempotent. It forgets a key's mapping only after the matching native unsubscribe succeeds, so later use starts a fresh thread.
The runtime configures no durable Codex history globally.
Native thread creation does not send an ephemeral flag; thread lifetime is instead controlled by the shared process and explicit idle close.
Dropping a live `Turn` rejects pending calls and interrupts that turn. Dropping all adapter handles closes and reaps the shared process.
## Shim lifecycle
A `Shim` is a sequential, single-conversation owner that may share an `Adapter` with shims for other keys.
Externally recorded boxes remain ordered, prefix the next fresh turn, and clear only after start acceptance; generated call boxes are output only.
Each native dynamic call is converted exactly once and passed to the injected launcher in provider order.
Once launch is accepted or queued, the shim immediately answers that exact call with `ASYNC_TOOL_ACKNOWLEDGEMENT`; no current-turn tool result, polling, batching, count limit, or hidden turn is introduced.
`infer` continues the same native turn through `Done` and returns one atomic ordered output, coalescing adjacent text.
A launcher rejection certifies no launch. Failure after an accepted start returns no partial output and makes that shim unusable; accepted effects must not be retried blindly.
`Shim::close_conversation` is available only while the shim is ready, closes its idle runtime conversation, and retains pending external boxes for a later fresh thread.
## Diagnostics and evidence
`Adapter::diagnostics` returns a snapshot of captured child stderr bytes, and errors carry the same diagnostic channel separately from their display message.
Diagnostics are not automatically placed in prompts or user-visible error text. Treat the raw bytes as operationally sensitive and disclose them only through an explicit trusted path.
Transport, runtime, shim, publication, consumer selection, deployment, and live provider behavior are separate states.
Behavioral verification belongs to the concrete-package testkit; this facade has no copied inline fake-server tests.
A successful facade check proves compilation and documentation against the selected concrete crates, not compatibility with any real provider executable or schema.