# Cross-Model Dispatch

**Status:** Phase 5 (Review & Verification) pattern
**Primary:** Gemini CLI
**Secondary (opt-in):** Codex CLI via `/gmd:external-agents`
**Mandatory fallback:** Claude Sonnet via `Task(subagent_type=gmd-verifier)`

## Purpose

GMD uses external CLIs (Gemini, Codex) for second-opinion verification on high-stakes work. When an external CLI is unavailable, disabled, or exceeds its timeout budget, dispatch falls back to a fresh-context Claude subagent. There is no silent-proceed path.

## Tier Vocabulary

The complexity tier names **match Phase 4.1's COMPLEXITY_MODEL vocabulary** (references/model-profiles.md §Complexity Tiers) — one vocabulary across subsystems. Reusing `simple`/`standard`/`complex` here means a single audit can flow a tier through both model-profile resolution AND cross-model timeout selection without translation.

| Tier | Timeout Budget | Example Use |
|------|----------------|-------------|
| simple | 60s | Single-file review, skill audit |
| standard | 180s | Phase-level multi-file diff |
| complex | 300s | Milestone integration, full codebase |

Defaults live in `.planning/config.json` under `workflow.cross_model_timeouts`. Users can tune per-project without editing command files.

## Dispatch Contract

Every cross-model dispatch MUST satisfy:

1. **Config-gated:** Check `.claude/external-agents.json` for CLI enablement before invoking.
2. **Availability-gated:** `command -v <cli>` before attempting invocation.
3. **Timeout-bounded:** Wrap invocation in `timeout ${TIER_SECONDS}s <cli> ...`.
4. **Fallback-guaranteed:** On any non-zero exit (failure, timeout, disabled, missing), dispatch a Claude fallback via `Task(subagent_type=gmd-verifier)` with `--complexity <same-tier>`.
5. **Output captured:** Primary output is captured to a temp file, printed on success, deleted on both paths.

If any of these fail at audit time (`tests/phase-05/audit-cross-model-tiered-timeouts.sh`), the build fails.

## Primary Dispatch Commands

- `/gmd:gemini-verify` — Gemini primary (CONTEXT.md lock)
- `/gmd:codex-verify` — Codex opt-in via /gmd:external-agents toggle

Both commands share the tier vocabulary and fallback contract. They differ only in:
- CLI binary invoked (`gemini` vs `codex`)
- CLI-specific flags for non-interactive + output capture

## Gemini CLI Invocation Shape

Verified against `gemini --version` 0.34.0:

```bash
cd "$(mktemp -d)" && timeout "${TIMEOUT}s" gemini \
  --prompt "$AUDIT_PROMPT" \
  --approval-mode plan \
  -o text
```

Rationale for each flag:
- `--prompt` (`-p`) — non-interactive headless mode; without it Gemini launches the TUI.
- `--approval-mode plan` — read-only mode equivalent to `codex --sandbox read-only`; Gemini cannot edit files.
- `-o text` — plain stdout; avoids JSON envelope that would need post-processing.
- `cd "$(mktemp -d)"` — approximates `--ephemeral` by starting in a clean working directory.

No direct `--output-last-message` equivalent exists in Gemini; stdout is captured via shell redirection to a `mktemp` file.

## Codex CLI Invocation Shape

Verified in `commands/gmd/codex-verify.md`:

```bash
codex exec \
  --full-auto \
  --ephemeral \
  --sandbox read-only \
  --output-last-message "$CODEX_OUT" \
  "$CODEX_PROMPT"
```

Codex is wrapped in a timeout inside `/gmd:gemini-verify`'s sibling flow (the codex path predates tiered timeouts and runs unbounded today; if codex is promoted into tiered-timeout parity later, it should adopt the same `timeout ${TIER_SECONDS}s` wrapper).

## Fallback Invocation Shape

```bash
FALLBACK_MODEL=$(node bin/gmd-tools.cjs resolve-model gmd-verifier --complexity "$TIER" --raw)
# Task(
#   subagent_type="gmd-verifier",
#   model="$FALLBACK_MODEL",
#   prompt="<second_opinion_audit complexity='$TIER'>${ORIGINAL_PROMPT}</second_opinion_audit>"
# )
```

Why `gmd-verifier`: it already has the two-stage verification workflow (plan 05-03) and knows how to produce structured reports. Spawning a generic general-purpose agent would duplicate this plumbing.

Why `--complexity $TIER`: the fallback's model selection matches the tier so a `complex` audit doesn't get silently downgraded to a Haiku. Complexity flows through Phase 4.1's COMPLEXITY_MODEL resolver (see references/model-profile-resolution.md).

## Anti-Patterns (from Phase 5 RESEARCH.md Pitfalls)

- **Silent proceed on CLI failure** (Pitfall 5): every `timeout` call must have a fallback branch. The audit counts `timeout-gemini` occurrences and verifies a matching fallback count `>= timeouts`.
- **Independent tier vocabularies**: do not invent new tier names — reuse `simple`/`standard`/`complex` from Phase 4.1. If you find yourself writing `fast`/`slow`/`xlarge`, stop.
- **Logic in hidden helper scripts** (Pitfall 3): dispatch logic must be inline in the command markdown so audits can grep it. Do not extract into `bin/cross-model-dispatch.cjs` — the entire point of Phase 5 is that the dispatch is readable in the command file.

## Open Questions

1. **Gemini CLI flag stability**: Flags verified against v0.34.0 at time of writing. If Gemini CLI renames `--approval-mode plan` or drops `-o text`, update `commands/gmd/gemini-verify.md` — the dispatch contract stays stable, only the invocation shape changes.

2. **Gemini behavior on SIGTERM**: Not yet verified against a real long-running prompt. Assumed compatible with GNU `timeout`. If `gemini` ignores SIGTERM on timeout, wrap in `timeout --kill-after=5s ${TIER_SECONDS}s gemini ...`.

3. **Codex tiered-timeout promotion**: Codex currently runs unbounded. If cross-model load grows, `/gmd:codex-verify` should adopt the same `timeout ${TIER_SECONDS}s` wrapper as Gemini. Mechanical change; not needed for Phase 5 closure.

## References

- `commands/gmd/codex-verify.md` — sibling command, structural template
- `commands/gmd/gemini-verify.md` — this pattern's primary implementation
- `references/model-profiles.md` — COMPLEXITY_MODEL source of truth for tier vocabulary
- `references/model-profile-resolution.md` — `resolve-model --complexity` CLI shape
- `.planning/phases/05-review-verification/05-RESEARCH.md` — Pattern 5 original derivation
- `tests/phase-05/audit-cross-model-tiered-timeouts.sh` — the audit that enforces this contract
