Downstream Contracts
The contracts below are load-bearing and version-drifting. Any change to the code that speaks them MUST update this file in the same commit (discipline inherited from codex-image-in-cc).
OpenAI Images API (src/drivers/image/openai.rs)
- Base URL:
drivers.image-openai.base_url(defaulthttps://api.openai.com/v1). - Auth:
Authorization: Bearer <key>; key read from the env var named byapi_key_envat call time; never stored, never logged. generatewithout refs →POST {base}/images/generations, JSON body{model, prompt, n?, size?, quality?}— absent options are omitted, never null.generatewith refs →POST {base}/images/edits, multipart form: text fieldsmodel,prompt, optionaln/size/quality; each ref is a file part namedimage[](gpt-image-1 multi-image form).edit→POST {base}/images/edits, multipart form:model,prompt, input file partimage, optional file partmask.- Response contract:
200JSON{"data": [{"b64_json": "<base64 png>"}]}.gpt-image-1always returnsb64_json(nourlvariant is handled). - Files are written to
out_dir(default./uplink-images/) as<compact-UTC-ts>-<n>.png; results carry absolute paths.
Codex CLI (src/drivers/image/codex.rs)
- Spawn:
<codex_bin> exec --sandbox workspace-write --skip-git-repo-check [--image <abs>]... "<instruction>"— argv vector, never a shell.--sandbox workspace-writereplaces the deprecated--full-auto(hidden fromexec --helpsince ~0.144.6 but semantically equivalent for non-interactiveexec; workspace-write is required so imagegen can save the output file into the CWD). - stdin MUST be
Stdio::null(): codex exec blocks reading stdin otherwise (documented hang, inherited from codex-image-in-cc). - Reference/input images are passed BOTH as
--image <abs>flags and as absolute paths inside the instruction text: the 0.144+ extension-backed image tool readsreferenced_image_pathsfrom the text, while 0.142–0.143 use the--imageattachments. Dropping either side breaks one version range. - Output contract: the instruction requires one
SAVED: <absolute path>line per saved image; stdout is parsed ONLY for those lines. Everything else codex prints is ignored — never re-parse LLM prose. - Doctor gates:
codex --versionparseable and ≥ 0.142.0;codex login statusexits 0 when logged in;codex exec --helpadvertises--sandboxand--image. - Timeout: one codex run is capped at 600 s (
Timeouterror beyond that). - Every spawn of
codex_bin(exec, doctor probes) retries up to 5× on ETXTBSY with short backoff — the classic fork/exec race when the binary was just written (cargo applies the same mitigation); surfaced as flaky spawn failures in parallel test runs.
Changelog
- 2026-07-23: all codex spawns gained ETXTBSY retry (5×, short backoff) —
first GitHub Actions run exposed the fork/exec race as a flaky
cargo test --libfailure; reproduced locally at iteration 1 of a 200-run stress loop. - 2026-07-23: codex spawn/doctor switched from
--full-autoto--sandbox workspace-write— codex-cli 0.144.6 hides--full-autofromexec --help(still parses as a hidden alias), which false-DEGRADED the doctor gate; found in live smoke testing. - 2026-07-22: initial version (M3 openai + M4 codex as shipped).