codex-channels normalizes interactive work into a small set of kinds:
approval_requestpermissions_requestuser_input_requestelicitation_requestprogress_updateresolvedcancellederrored
An interaction should include:
- stable interaction id
- source identity
- optional Codex thread / turn / request correlation
- user-facing payload
- routing policy metadata
- lifecycle state
A response should include:
- target interaction id
- action (
accept,decline,cancel,text) - optional values
- response metadata
- response timestamp
- HTTP / CLI for general custom integrations — if you are wiring a Python, Rust, Java, or other external tool into
codex-channels, prefer the local HTTP runtime or the CLI commands that sit on top of it. - JSON-RPC for the Codex bridge boundary — JSON-RPC matters when
codex-channelsis translating Codex app-server requests, but it should not be the default requirement for every third-party integration.
The Codex app-server protocol already contains primitives for:
- command approval
- file change approval
- permissions approval
- tool user input
- MCP elicitation
codex-channels should map those into the generic interaction model instead of inventing a parallel semantic layer.
Backends should receive a normalized interaction and remain ignorant of the original app-server or MCP wire protocol.
At minimum, the runtime should preserve:
interaction.idcodex.threadIdcodex.turnIdcodex.requestIdsource.name
- pending
- delivered
- resolved OR cancelled OR errored
The runtime should be able to emit resolution even when a source request is cleared by lifecycle events rather than a user reply.