ADR-0002 — The agent pipeline is harness-agnostic¶
Status: Accepted · 2026-09-06
Context¶
The delivery pipeline was hardcoded to Google Antigravity's agy, with fallback only between
models within that one CLI. During this repository's first real run, Antigravity exhausted both
fallback tiers mid-implementation and two approved plans stalled at Blocked with nothing else to
try — a single vendor's quota halted delivery entirely.
Decision¶
Coding-agent CLIs are described declaratively in .github/scripts/harnesses.py: a binary, an argv
template, a model chain, and credential keys. Antigravity, Claude Code, Codex, Kimi, Grok, Cursor,
and opencode ship in the registry.
- Fallback escalates across harnesses, not only across models.
- Harnesses whose binary is absent from
PATH, or whose credentials are unset, are skipped, not failed. AGENT_HARNESS_CHAINandAGENT_HARNESS_CONFIGoverride order and every field at runtime.- Prompts are passed as argv elements, never through a shell.
Alternatives rejected¶
- Stay single-vendor. Demonstrated to halt delivery on one provider's quota. Not hypothetical — it happened during the run that motivated this ADR.
if/elifper CLI in the runner. Every new CLI edits the core retry loop, and each upstream flag rename becomes a code change, a review, and a container rebuild.- A wrapper shell script per CLI in the image. Moves invocation into shell — where prompt quoting becomes an injection risk — and puts it beyond the reach of unit tests.
- An LLM API abstraction instead of CLIs. These tools are agents, not completions endpoints: they carry their own tool loops, permissions, and repository awareness. Reimplementing that is the project, not a dependency.
Consequences¶
- Invocation flags are a maintenance surface. Mitigated by making every field overridable from a repository variable, so upstream drift never requires a code change.
- The container is larger and its build tolerates per-CLI failure, printing a manifest of what actually landed rather than pretending.
- Harness behaviour differs — output verbosity, tool permissions, repository conventions. Prompts must not assume any one CLI's habits.