Cross-CLI SDD Orchestration

The cross-CLI workflow coordinates Codex artifact creation with independent Claude Code review. It reuses the existing Spec Kit and review-* skills rather than replacing their instructions.

Automated development runner

scripts/run_ai_flow.py launches the writer and reviewer sequentially, using the same specification, plan, tasks and implementation protocol. This adapts the pinned-role and resumable execution approach from the EW4All document runner to this repository's existing Spec Kit stages. It uses only Python's standard library and the installed, authenticated codex and claude CLIs.

Setting Default
Writer Codex, gpt-6-astra, xhigh effort
Reviewer Claude Code, claude-opus-5, xhigh effort
Review rounds Four per stage
Invocation timeout 3,600 seconds per writer/reviewer invocation

Model identifiers are explicit, not floating aliases. Both CLIs expose model selection; Codex accepts the model_reasoning_effort configuration and Claude accepts --effort. Consult the Codex CLI reference and Claude Opus 5 documentation. CLI flag support does not establish account access to a model. The runner does not substitute another model on failure; logs retain the requested invocation.

Preview the defaults without writing state or calling either model:

./.venv/bin/python scripts/run_ai_flow.py --dry-run

Start a bounded development package:

./.venv/bin/python scripts/run_ai_flow.py \
  --flow-dir .ai-flow/cache-reliability \
  --brief 'Repair cached map authorization and freshness with fail-first regressions; add the existing Node suite to CI. Preserve PostGIS authority and existing role boundaries.'

For a larger brief, use --brief-file path/to/brief.md instead of --brief. Use a separate named flow directory for each package. The previous manual flow at .ai-flow/ is left intact. All runner state directories must be under the repository's ignored .ai-flow/ directory.

Override either role, model, effort, round limit or invocation timeout when creating a flow:

./.venv/bin/python scripts/run_ai_flow.py \
  --flow-dir .ai-flow/another-package \
  --brief-file tasks/development-brief.md \
  --writer codex --writer-model gpt-6-astra --writer-effort high \
  --reviewer claude --reviewer-model claude-opus-5 --reviewer-effort xhigh \
  --max-rounds 3 --timeout-seconds 5400

--writer claude --reviewer codex swaps the roles and selects each agent's corresponding default model. Writer and reviewer must use different agents. Model-specific effort availability is ultimately checked by the selected CLI and provider; the runner validates the supported effort vocabulary.

An optional --config path/to/defaults.json accepts partial settings:

{
  "writer": {"agent": "codex", "model": "gpt-6-astra", "effort": "xhigh"},
  "reviewer": {"agent": "claude", "model": "claude-opus-5", "effort": "xhigh"},
  "max_rounds": 4,
  "timeout_seconds": 3600
}

Precedence for a new flow is built-in defaults, then JSON configuration, then CLI overrides. The resolved settings and brief are pinned in runner.json. Resume with only the flow directory; different settings or a different brief are rejected rather than silently changing a running review:

./.venv/bin/python scripts/run_ai_flow.py --flow-dir .ai-flow/cache-reliability
./.venv/bin/python scripts/ai_flow.py --flow-dir .ai-flow/cache-reliability status

Runner handoffs and recovery

Each invocation reads the authoritative stage skill and returns structured JSON. The runner, rather than the model, publishes stages, records verdicts, archives superseded reports and finishes fully approved flows. It prints progress every 15 seconds. Prompts, requested CLI arguments, output and errors are retained in the flow's runs/ directory. These files can contain private project material; they are local and ignored by Git.

The Claude reviewer has only Read, Glob and Grep tools. The Codex reviewer uses the read-only sandbox. Reviewers receive a Git snapshot and writer evidence; they must distinguish that evidence from checks they personally execute. The runner compares repository-file fingerprints before and after review and refuses approval if files changed. It also checks the published fingerprint before a resumed review. It detects changes but does not revert them automatically.

The writer uses Codex's workspace-write sandbox or Claude's acceptEdits mode. The runner enables neither CLI's permission-bypass option. Tool denials, missing evidence, required clarifications or actions requiring owner approval must be reported as HUMAN_REVIEW; a zero process exit alone never means approval. Repository restrictions on package installation, migrations, Black and make check still apply. Model prompts are behavioral instructions, not an operating-system guarantee against every prohibited action.

For a writer clarification, read writer-question.md, place the answer in a UTF-8 file, and resume with --answer-file path/to/answer.md. Answers are retained and passed to later invocations. Without an answer, the writer is not retried.

For a reviewer HUMAN_REVIEW, inspect <stage>-review.md, make an explicit owner decision and use the existing protocol before resuming:

./.venv/bin/python scripts/ai_flow.py --flow-dir .ai-flow/cache-reliability \
  resolve-human spec CHANGES_REQUIRED
./.venv/bin/python scripts/run_ai_flow.py --flow-dir .ai-flow/cache-reliability

Replace spec with the paused stage and use APPROVED only for an actual owner approval. Do not edit published artifacts directly while awaiting review; return them to the writer through the review decision. If changed files are detected, inspect and restore the intended published state before resuming.

Exit codes: 0 completed (or dry-run), 2 execution/configuration failure, 3 owner input required, 130 keyboard interruption. Failed agent invocations do not advance the stage. A failed writer can leave partial edits, which the next writer invocation must inspect. A failed reviewer can be rerun against the unchanged published work. Timeout and Ctrl+C terminate the child process group.

Only one automated runner may execute in a worktree. Do not simultaneously run the manual two-CLI loops, reset the protocol, or change the active feature there. The manual helper does not acquire the runner lock. In particular, resetting the root .ai-flow/ would delete nested named flows, so preserve required review evidence and prefer a new named directory instead.

No live model run is part of the automated runner test suite. Validate its local configuration and protocol/process tests with:

./.venv/bin/python -m unittest discover -s tests -p test_ai_flow_runner.py

Starting a manual two-CLI flow

Open Codex and Claude Code in the same repository worktree. The commands may be started in either order because each side waits for the other.

In Codex:

$start-sdd <feature description>

In Claude Code:

/review-sdd

Only these two initial commands are normally required. Codex progresses through specification, plan, tasks, and implementation. Claude reviews each published stage and then waits for the next one.

Codex                         Shared state                    Claude
  | create/revise artifact        |                              |
  | publish stage --------------> | *.ready                     |
  |                               | <-------------- claim stage |
  | wait for verdict              | *.reviewing                  |
  |                               | <------- report + status     |
  | read verdict <--------------- |                              |
  | continue or revise            |                              |

Verdicts

Claude publishes one exact machine-readable status:

  • APPROVED: Codex continues to the next stage.
  • CHANGES_REQUIRED: Codex addresses Critical and Important findings, then republishes the same stage.
  • HUMAN_REVIEW: both automated loops stop for an owner decision.

The default maximum is four review rounds per stage. A further blocking verdict is escalated to HUMAN_REVIEW rather than creating an unbounded revision loop.

Runtime State

scripts/ai_flow.py owns all state transitions and atomic marker changes under .ai-flow/. The directory is local runtime state and is ignored by Git.

Useful inspection commands:

./.venv/bin/python scripts/ai_flow.py status
./.venv/bin/python scripts/ai_flow.py --help

The latest review is available at .ai-flow/<stage>-review.md. Earlier review rounds are archived under .ai-flow/history/ for the duration of the flow.

Recovery

Bounded implementation invocations

The CLI runner accepts --implementation-checkpoints path/to/scopes.json, a nonempty JSON list of ordered scope descriptions. Supply it on a new flow or before an existing flow first publishes implementation. Scopes become pinned; ordinary resume needs only the original --flow-dir.

Each completed non-final scope returns CHECKPOINT. The runner saves its report and advances to the next writer invocation without publishing an implementation or consuming a review round. Only the final scope may return READY; the normal independent reviewer then assesses the entire implementation. Review corrections can revisit earlier scopes. Checkpoint completion is writer-reported progress, not independent approval.

A timeout or provider failure stops the runner and leaves the current scope unchanged. Resume with the same command; existing task/evidence files provide the recovery point within that scope. No automatic retry loop or acceptance waiver is introduced. Keep scopes small enough for the configured invocation timeout.

For the interrupted reliability package:

./.venv/bin/python scripts/run_ai_flow.py --flow-dir .ai-flow/reliability-01 \
  --implementation-checkpoints tasks/reliability-01-checkpoints.json

Both skills resume persisted state after an interrupted CLI session. Run the same skill again; do not delete or edit marker files manually.

If Claude fails after claiming a stage but before publishing its report, return the claim and restart /review-sdd:

./.venv/bin/python scripts/ai_flow.py release <stage>

After a HUMAN_REVIEW decision, Codex records the owner's APPROVED or CHANGES_REQUIRED choice through resolve-human and resumes the flow.

Start a separate flow only after preserving any review evidence that is needed:

./.venv/bin/python scripts/ai_flow.py reset --confirm

The orchestration does not commit, push, create or merge pull requests, or deploy. Those actions remain explicit owner decisions.