feat(FAFF-593): codex spawn family for faff engine call — codex exec --json child transport#495
Merged
alechill merged 7 commits intoJul 25, 2026
Conversation
…spawn codex exec --json, parse the event stream, backends: entry shape
…--json child transport Adds the third engine transport family: provider codex dispatches a producer through a spawned codex exec --json child (prompt on stdin, JSONL event stream on stdout, final agent message as the producer block) instead of an HTTP POST. - config.js: codex in ENGINE_PROVIDER_FAMILY; provider-conditional required fields in validateEngineRef (codex: provider+model, host/reasoning_off/auth none each refused with a named error); effort refusal message generalised to "engine backend"; resolveEngineForLane returns the codex-shaped record (binPath, no host). - backends.js: bin_path joins the Backend record; keyless codex derives subscription-seat; the codex seat admits on any harness (the seat travels with the codex CLI's own login state, not the harness); checkRealizable skips the host-presence test for codex only. - engine-codex.js (new): buildCodexArgv / parseCodexEvents (fail-loud JSONL, events kept for the FAFF-604 spend read) / classifyCodexFailure / runCodexCall with injectable spawnFn, plus the codex selftest table folded into faff engine --selftest. - engine.js: cmdEngine forks to the codex path on resolved family, with its own failure tags (no HTTP host tag). No codex binary was installed on the build machine: parser/argv shapes follow the spec's codex-rs-sourced assumptions verbatim; live re-pinning is a flagged needs-human item. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jMqrXT3E21jv8vrqLYJa2
…spawn Read-time: engine:codex-seat resolves on an allowlisted lane; host-present / reasoning_off / auth-none each exit 2 with the named error; the non-allowlisted lane guard is unchanged. Dispatch: happy path, seat-probe fail (6), ENOENT (5), malformed JSONL (7), no agent message (7), auth-shaped child failure (6), api_key_env unset before any spawn (6) — all through the injected spawnFn, zero real spawns or network. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jMqrXT3E21jv8vrqLYJa2
…is HTTP one-shot plus codex CLI spawn Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jMqrXT3E21jv8vrqLYJa2
…anch of ADR-0054's fork (FAFF-593) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016jMqrXT3E21jv8vrqLYJa2
…d throw — adversarial-review finding
alechill
force-pushed
the
faff-593-faff-engine-call-gains-a-codex-engine-spawn-codex-exec-json
branch
from
July 25, 2026 15:17
d94cf25 to
7a859bd
Compare
alechill
deleted the
faff-593-faff-engine-call-gains-a-codex-engine-spawn-codex-exec-json
branch
July 25, 2026 15:21
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds the
codexspawn family tofaff engine call: abackends:entry withprovider: codexdispatches a producer through a spawnedcodex exec --jsonchild process — the first non-HTTP transport family, extending ADR-0054's per-lane transport fork (recorded as ADR-0090). Spec:docs/specs/2026-07-25-FAFF-593-codex-engine-for-faff-engine-call-design.md(full spec with rationale on Linear FAFF-593).What ships:
engine-codex.js— purebuildCodexArgv/parseCodexEvents/classifyCodexFailure+runCodexCall(injectable spawn/env/mkdtemp; synchronous int return; fail-loud on every path, no retry, no fallback to the session model).codexin the provider family map; provider-conditionalvalidateEngineRef(nohost, noreasoning_off, noauth: none); keyless codex derivessubscription-seat;portableMatrixAdmitsadmits a codex seat on any harness;checkRealizableno longer silently skips hostless codex refs; new optionalbin_pathbackend field.exec --json --ephemeral --skip-git-repo-check --sandbox read-only -m <model> -, prompt on stdin (system + blank line + user), fresh temp cwd removed after,OPENAI_API_KEYinjected only in api-key mode.faff engine --selftest; 15 new tests intest/engine-call.test.mjs;docs/architecture/harness-coupling.mdrow updated.Acceptance Criteria
backends:declares a codex engine, the fork runscodex exec --jsonwith the full posture flag setVerified: selftest argv-shape row +
test/engine-call.test.mjshappy path (deepEqualon argv, exactly one exec spawn)Verified: tests — unset
api_key_env→ exit 6 before any spawn; seat-probe fail → exit 6 namingcodex login; auth-shaped child failure → exit 6faff contractpath as a Claude-engine forkVerified: happy-path test asserts stdout is the final agent message verbatim beyond trim (downstream
faff-contract:*parsing unchanged)requires: localchain refuses (egress external)Verified: selftest rows (refusal + deliberate
deriveEgress → external)login statusexit codes,OPENAI_API_KEYhonouring, exit-on-fatal, flag availability) against an installed codex binaryNeeds human verification: no codex binary on the build machine; shapes follow the spec's codex-rs-sourced pins verbatim (with a commented
item_type/typedrift tolerance to narrow at re-pin). The code is inert until an operator configures a codex backend, and every assumption-failure mode lands on a named loud exit. Flagged in the module banner + ADR-0090.Review: Phase 1 (structural, five-pass) pass with zero findings; Phase 2 adversarial second opinion (
nvidia/z-ai/glm-5.2) raised 3 major / 2 minor — one valid (mkdtemp throw escaping the int-return contract, fixed in 210d17d with a new selftest row), the rest dispositioned with evidence on the tracker issue.Gates: validate-adapters PASS (19 skills), full suite 2476/2476, engine selftest PASS.
🤖 Generated with Claude Code
https://claude.ai/code/session_016jMqrXT3E21jv8vrqLYJa2