Harness integration
Aider
HarnessRouter v0.19.0 adds Aider 0.86.2 as backend `aider`; native UHP adoption by Aider is not established.
Status first
Section titled “Status first”HarnessRouter v0.19.0 adds Aider as its thirteenth backend, pinned to aider-chat 0.86.2. PR #211 merged on 19 September 2026 as ccf4af6647182e7175788353f8b0287829054e07, and GitHub Release v0.19.0 was published at 06:19:09 UTC pointing to that same commit. Stable and checked current main are therefore the same source coordinate at this cutoff.
PyPI publishes aider-chat 0.86.2, uploaded 12 February 2026. HarnessRouter pins that exact package version because its adapter deliberately reaches an Aider Python integration surface that Aider itself says is not officially supported or documented and may change without backward compatibility.
HarnessRouter backend support does not establish native UHP support by Aider. No reviewed Aider primary source at this cutoff publishes native UHP adoption.
Why HarnessRouter drives Aider in process
Section titled “Why HarnessRouter drives Aider in process”The adapter does not launch Aider and infer structured state from terminal text. Its driver calls Aider’s own Python entry point with return_coder=True, then hooks the resulting coder in process.
The reason is evidence fidelity. PR #211 documents a measured ambiguity in Aider’s ordinary stdout: model prose and Aider diagnostics share one text channel, so an answer that merely contains an error-looking line can be byte-identical to a real provider failure. A regex normalizer would therefore risk turning ordinary model prose into a failed turn.
The in-process seam keeps those sources separate: assistant output, tool errors, warnings, edit evidence, shell decisions and final result state can be emitted as distinct runner events. That improves adapter observability, but it comes with a compatibility cost because the Python scripting surface is not a stable public API. Exact version pinning and install-time symbol checks are therefore part of the integration contract.
Shell commands are the effective tool surface
Section titled “Shell commands are the effective tool surface”For this backend, the model’s executable tool surface is primarily the shell commands Aider extracts from fenced command blocks. HarnessRouter intercepts Aider’s explicit shell confirmation path and applies a policy gate to the exact proposed command before execution.
The gate distinguishes ordinary shell execution from HarnessRouter’s MCP bridge calls. A disabled Shell or Bash capability rejects shell execution; a command of the form hr-mcp call <server> <tool> is also checked against disabled MCP tool names. Approved commands produce explicit decision and result evidence instead of being treated as unstructured prose.
This is HarnessRouter adapter enforcement, not an Aider-native UHP tool protocol and not a new UHP rule. It also means the adapter must keep command extraction, policy enforcement and execution evidence aligned: a command path that escapes the gate would be a capability-policy defect even if Aider itself can execute it.
MCP is bridged, not native Aider MCP
Section titled “MCP is bridged, not native Aider MCP”PR #211 adds runner/aider_mcp_bridge.py and exposes configured MCP servers to Aider through an hr-mcp command surface backed by the official MCP SDK. The model discovers and invokes those MCP tools through shell commands, and the HarnessRouter gate can refuse a disabled tool by name.
No reviewed primary evidence establishes a native MCP client in the pinned Aider runtime used by this adapter. The MCP behavior documented here therefore belongs to HarnessRouter’s bridge, while MCP itself remains authoritative for MCP wire semantics.
This distinction matters for portability: replacing the HarnessRouter adapter with stock Aider does not imply the same MCP discovery, transport, policy or event-evidence behavior.
Session, workspace and instruction boundaries
Section titled “Session, workspace and instruction boundaries”HarnessRouter stores Aider-specific state under .harness/aider/ inside the runner’s checkpoint domain and invokes Aider with --restore-chat-history. The adapter therefore gives follow-up turns durable conversation context across sandbox recycle without letting Aider own the workspace Git history.
The driver also disables Aider auto-commits and dirty commits because HarnessRouter owns checkpoint/workspace commit semantics. Aider’s repository-map cache is relocated under .harness/aider/ so private harness state does not appear as a produced user file.
Harness instructions are injected through Aider’s model-level system_prompt_prefix hook rather than sent as an ordinary user/read-only message. The adapter also folds Aider’s edit-format examples into the system message so those examples do not become false earlier user turns in the conversation. These are prompt-role and persistence corrections specific to the integration.
Runtime bounds and model metadata
Section titled “Runtime bounds and model metadata”Aider’s upstream request timeout can otherwise be unbounded, so HarnessRouter supplies a default 300-second timeout through HR_AIDER_TIMEOUT. The adapter also maps the HarnessRouter turn budget onto Aider’s reflection bound.
Provider/model routing presents another adapter boundary. HarnessRouter uses an OpenAI-compatible relay shape, while Aider/LiteLLM model metadata may be keyed by an unprefixed model id. The driver writes available bare-id metadata back for the prefixed runtime id when possible so Aider can recover real context/output limits rather than reporting a zero-sized context window. Unknown models remain unknown rather than receiving invented limits.
Provider compatibility and resource cost
Section titled “Provider compatibility and resource cost”HarnessRouter’s current self-hosting guide lists Aider for anthropic, openai, openrouter, azure-foundry, google, tokenrouter, vercel, llmtr and custom connections. It does not list Aider for the Bedrock row at this cutoff.
The same guide calls Aider the largest default backend environment at roughly 735 MB and about 90 seconds to install on a fresh volume, and recommends omitting it from HR_BACKENDS when it is not needed. Those are HarnessRouter deployment observations, not upstream Aider package-size guarantees.
Evidence boundary
Section titled “Evidence boundary”The merge commit reports the final reviewed candidate with:
- 241/250 console scenarios across 50 model ids;
- 4/4 Harness Plugins matrix coverage;
- 3/3 custom skill + script + MCP checks; and
- 75/75 UHP conformance for the candidate runtime.
These numbers answer different questions. The console/plugin/custom rows are HarnessRouter runtime/provider evidence, not UHP conformance. The reported 75/75 run is meaningful release-candidate validation for PR #211 and the code that became v0.19.0, but it is not a checked-in versioned HarnessRouter Full report: the latest checked README/JSON evidence in the repository still records pre-X-09 74-check Full runs. Do not silently replace those historical artifacts with the PR’s candidate result.
Release boundary
Section titled “Release boundary”At this cutoff:
- UHP:
2026-09-12Draft. - HarnessRouter stable:
v0.19.0/ccf4af6647182e7175788353f8b0287829054e07, thirteen released backends includingaider. - HarnessRouter current
main: the sameccf4af66source coordinate. - Aider pin:
aider-chat 0.86.2. - Native Aider UHP adoption: not established.
- Aider MCP behavior described here: HarnessRouter bridge behavior, not established as native Aider MCP support.
See HarnessRouter for the reference-implementation boundary, release tracker for release coordinates, adoption for the native-adoption distinction, and UHP vs MCP for the protocol-layer boundary.