Skip to content

ACP compatibility campaign

Current delivery scope (owner decision, 2026-09-07): Codex, Claude and Grok. The other six integrations are deferred; their recorded results below remain partial or blocked measurements, not current support claims. See the acceptance verdict.

Measured on 2026-09-06, Linux x86_64, using Greatminds' common AcpTransport and agent-client-protocol==0.11.1. Each executable ran in a fresh temporary workspace. Initialization and session probes do not send model prompts. A separate explicit inference stage sends one synthetic text request per tested installation.

Recorded initialization results

Harness Tested installation ACP argv Initialize
Codex codex-acp 1.10.0, Codex CLI 0.149.1 selected with CODEX_PATH codex-acp Protocol 1 accepted
Claude claude-agent-acp 0.75.1, Claude Agent SDK 0.3.257 claude-agent-acp Protocol 1 accepted
Qwen Code 0.19.6 qwen --acp Protocol 1 accepted
Kimi Code 0.39.1 kimi acp Protocol 1 accepted
Grok 1.0.13, build 5e9a58528b76 grok --no-auto-update agent stdio Protocol 1 accepted
Cline 3.0.50 cline --acp Protocol 1 accepted
Gemini CLI 0.49.0 gemini --acp Protocol 1 accepted
OpenHands CLI 1.16.0 openhands acp Protocol 1 accepted
Cursor CLI 2026.06.15-18-00-12-6f5a2cf cursor-agent acp Protocol 1 accepted

The recorded JSON retains the protocol responses with arbitrary metadata, host paths, process IDs, and raw logs excluded. Capabilities in that file are advertised, not exercised. Initialization proves that these installations speak to the shared client; it does not yet establish tool permissions, task execution, resumption, cancellation during inference, or a mixed-agent pipeline. Those remain required for support.

Session and minimal inference results

Harness Session without explicit authenticate Exact synthetic reply
Codex CLI 0.149.1 / adapter 1.10.0 Created Failed: selected model requires newer CLI
Codex CLI 0.153.4 / adapter 1.10.0 Created Passed
Claude SDK 0.3.257 / adapter 0.75.1 Created Passed
Grok 1.0.13 Created Passed
Cline 3.0.50 Created Not tested
Qwen Code 0.19.6 Authentication required (-32000) Not tested
Kimi Code 0.39.1 Authentication required (-32000) Not tested
Gemini CLI 0.49.0 Authentication required (-32000) Not tested
OpenHands CLI 1.16.0 Authentication required (-32000) Not tested
Cursor CLI 2026.06.15-18-00-12-6f5a2cf Authentication required (-32000) Not tested

Session and prompt evidence records these separate stages. The prompt asks for exactly ACP_PROBE_OK without tools. Passing means the streamed text matches, the agent returns end_turn, and the process exits during bounded shutdown. No tool or permission requests occurred in those prompts. This is not a domain task or mixed-agent pipeline test.

The older Codex returned a provider error as assistant text followed by end_turn. The exact-response assertion correctly rejected it. A stop reason alone is not proof of useful work; production task advancement requires validated typed results. The separately installed, lockfile-pinned Codex 0.153.4 passed the same request.

An authentication-required response does not prove that cached credentials are absent. Some servers require explicit ACP authentication before using an existing login. Manifests may specify auth_method; the supervisor verifies it was advertised and calls authenticate before creating or loading a session. It does not guess a method or silently choose another identity. Fresh explicit-auth attempts and their limitations are recorded below.

Restart, context, configuration, and cancellation

Harness Load after process restart Recall previous-turn token Cancel after first assistant text Explicit config selection
Codex CLI 0.153.4 / adapter 1.10.0 Passed Passed cancelled Model gpt-6-astra, mode read-only confirmed
Claude SDK 0.3.257 / adapter 0.75.1 Passed Passed cancelled Model default, mode default confirmed
Grok 1.0.13 Passed Passed cancelled No model config option advertised; not tested

Lifecycle evidence records each stage. Restart tests close the first agent process, then create another in the same workspace and call session/load with the privately retained session ID. The history test uses a different second prompt which does not contain the token. Historical updates emitted during loading are excluded from the second response assertion. This proves continuity for these individual harnesses; it does not transfer conversation history across different harnesses.

Cancellation tests wait for nonempty assistant text before sending session/cancel. All three returned cancelled and exited during bounded shutdown. Completion before the cancellation request is explicitly reported as unconfirmed, not passed. These tests do not yet cover cancellation while a tool or permission callback is pending. The supervisor and probe share advertised model/mode selection code; model configuration responses must confirm the requested value.

Live permission callbacks and operator responses

Permission evidence records a synthetic shell command that writes permission-ok to a file in a temporary project. Claude 0.75.1/SDK 0.3.257 requested approval; greatminds run permission ID --option ID answered once, the same run consumed it, and the file appeared before turn completion. Grok and Codex also passed with the explicit settings below. For those two explicit tests the file was directly observed absent while the request was pending.

The initial Grok run inherited ui.permission_mode = auto and performed the write without an ACP callback. Using grok --no-auto-update --permission-mode default agent --no-leader stdio produced the callback without changing user configuration. Codex's default agent mode also performed the ordinary workspace write without a callback. Its read-only mode delegates escalated approvals to the user but still allows ordinary workspace writes in this adapter version. The successful callback test selected that mode and explicitly requested sandbox_permissions=require_escalated for the harmless command. These are different approval triggers, not proof that every shell command in every harness requires an ACP approval.

The client ask policy routes callbacks to the operator; it does not override a harness's internal approval defaults. The executable's mode, cached settings, and execution boundary remain part of compatibility configuration. Complete permission policy parity and negotiated filesystem/terminal callbacks remain pending.

The supervisor permission probe (tools/acp_permission_probe.py in the source checkout) makes the scenario reproducible. It prints a temporary project/runtime location, submits one synthetic model request, and waits for an operator. It never approves a request. From that project's operator terminal, inspect greatminds run status, then inspect and answer its exact permission ID. The probe requires an observed pending request before the marker exists, a consumed one-time approval, and the expected file.

.venv/bin/python tools/acp_permission_probe.py \
  --adapter-version 0.75.1 --harness-version sdk-0.3.257 \
  -- /absolute/path/to/claude-agent-acp

Fixture tests additionally cover explicit rejection, cancellation during a pending callback, stale revisions, expired requests, conflicting replies, and SIGKILL before delivery of both pending and answered requests. Restart cancels those requests and preserves the input hold without spawning another agent. These crash/denial cases have not yet been repeated across all real executables.

OpenHands and Cursor initially could not create their normal per-user runtime directories under the filesystem-restricted test runner. Gemini initially could not reach its OAuth refresh endpoint. Codex initially could not initialize its SQLite runtime. Repeating initialization with normal filesystem/network access resolved these startup failures. The test selected the already installed Codex CLI explicitly; the adapter's separately installed dependency is Codex 0.153.4. That bundled combination subsequently passed the session and minimal inference stage above. The global CLI installation was not updated.

Mixed domain pipeline

The first real pipeline evidence is partial. A local feature task uses a task worktree and six configured unit tests for an inclusive numeric clamp function, including invalid bounds. Codex 0.153.4 implemented the function, requested daemon-run tests, and submitted a typed implementation handoff. Claude SDK 0.3.257 independently inspected it, requested its own test execution, and submitted a typed tests handoff. Both receipts passed domain gates and the task reached feature_review.

Grok 1.0.13 initially exhausted its 240-second prompt budget while waiting for an operator permission. The completed continuation records an explicit reviewer retry with a 600-second budget and one-time operator approvals. Grok independently ran all six tests and submitted an approved review through run submit --json. The daemon applied all three results, merged the implementation and transitioned the task to verified, with worktree cleanup. All six tests pass in the main checkout; an idle daemon restart changes no runs, results, or commands. This is operator-assisted evidence for one synthetic local task, not an unattended pipeline or a controlled performance comparison.

The pipeline probe (tools/acp_pipeline_probe.py in the source checkout) takes --config FILE with three ACP bindings for DEVELOPER, TESTER, and ARCHITECT-REVIEWER. It copies the manifests into a fresh temporary Git project, seeds a synthetic local plan, and replaces configured commands with the known local unit-test command. It never approves permissions or silently retries a held run. Its full fixture regression covers all three role transitions, evidence validation, daemon merge, worktree cleanup, main-branch test execution, and restart without duplicate work. That fixture result does not establish completion of the real pipeline.

The real run exposed two integration issues. Assigned context now identifies the CLI through the daemon's Python executable rather than assuming greatminds is on PATH; the final implementation also isolates module lookup from workspace files. Explicit stand_required: false plans no longer require fabricated stand observations. Local test blocks and configured command evidence still pass domain validation; stand-required or unspecified plans retain scope-specific stand gates.

Reproduce the probe

From an editable Greatminds checkout:

.venv/bin/python tools/acp_probe.py -- qwen --acp
.venv/bin/python tools/acp_probe.py --session -- kimi acp
CODEX_PATH=/absolute/path/to/codex .venv/bin/python tools/acp_probe.py \
  --env CODEX_PATH -- /absolute/path/to/codex-acp
.venv/bin/python tools/acp_probe.py --timeout 45 \
  --prompt 'Reply with exactly ACP_PROBE_OK and nothing else. Do not call any tools.' \
  --expect ACP_PROBE_OK -- /absolute/path/to/claude-agent-acp
.venv/bin/python tools/acp_probe.py --timeout 45 --resume \
  --prompt 'Remember TOKEN_42. Reply only SAVED.' --expect SAVED \
  --resume-prompt 'Return only the token from my previous message.' \
  --resume-expect TOKEN_42 -- /absolute/path/to/codex-acp
.venv/bin/python tools/acp_probe.py --timeout 45 --cancel-after 0.1 --cancel-on-output \
  --prompt 'Write the integers from 1 to 3000, one per line. Do not use tools.' \
  -- /absolute/path/to/codex-acp

The default probe sends only initialize and performs bounded transport shutdown. --session additionally creates a session. --auth-method ID explicitly selects an advertised authentication flow, which may require interactive login depending on the server and cached account. --prompt TEXT explicitly sends a model request and may consume provider usage; --expect TEXT checks the observed assistant response. --model ID and --mode ID require advertised choices. --resume restarts the process and loads its session; --resume-prompt and --resume-expect check a distinct follow-up. --cancel-after tests cancellation of a pending prompt; add --cancel-on-output to wait for streaming text first. Resume and cancellation are separate scenarios and cannot be combined in one invocation. It prints a versioned JSON report and returns nonzero on failure. Each probe retains a private report, process identity, stderr, and any assistant response in its temporary directory. Extra environment values are passed only through explicit --env NAME references; their values, assistant text, and arbitrary protocol metadata are excluded from stdout. Sensitive values must not be placed in executable arguments.

The adapter package definition (tools/acp_adapters/package.json) and npm lockfile (tools/acp_adapters/package-lock.json) pin the Codex and Claude test adapter installations, including resolved dependencies. Copy those two files to a separate writable test directory and run npm ci --ignore-scripts --no-audit --no-fund there. Select executables from that directory's node_modules/.bin/. The Node runtime used for the recorded test was 22.13.0. Installing test dependencies does not alter the global harness installations or a project's execution bindings.

Distribution references

Codex's upstream adapter exposes ACP over the Codex App Server and supports an explicit CODEX_PATH override. Claude's upstream adapter package uses the Claude Agent SDK. These adapters stay at the executable boundary; the Greatminds scheduler has no separate Codex or Claude wire protocol path in ACP mode.

Grok documents its stdio ACP command and update suppression. OpenHands documents its ACP CLI entrypoint, and Cursor documents ACP sessions and extension requests. Blocking extension requests and provider-specific optional capabilities must be explicitly negotiated or handled before the corresponding workflows can be declared supported. A listed command or an accepted initialization response is not a substitute for those tests.

Cline revalidation on 2026-09-07

The executable currently on this host reports Cline 3.0.61, whereas the earlier session-only evidence records 3.0.50. A fresh common-client probe created a session and sent a synthetic exact-response request without tools. session/prompt returned JSON-RPC -32603 (Internal error) with no assistant text. The private stderr diagnostic identified required re-authentication. The process exited during bounded cleanup, and the requested restart/load stage was skipped because the initial prompt failed. No account or model selection was changed.

Sanitized evidence records this failure. This access failure was resolved after the operator completed native login; the successful revalidation below supersedes the Cline access blocker. Creating an ACP session alone does not establish working provider credentials.

One-harness local preset on 2026-09-07

A fresh temporary Git repository completed the local clamp task using ordinary greatminds setup, project preset local --agent codex --apply, and the common daemon. The manifest used Codex 0.153.4 with codex-acp 1.10.0. The preset kept permission: ask; this task generated no permission callbacks. One manifest served developer, tester and reviewer in separate runs, while the planner remained on demand. The task supplied an explicit synthetic plan with no stand requirement.

Recorded evidence confirms three applied typed handoffs, three successful daemon command receipts, SYSTEM provenance for all resulting decision blocks, a merge changing only clamp.py, removal of the task worktree, six independently rerun unit tests, and restart without additional runs/results/commands. No native transport, deployment or publication was involved.

Role Compiled context bytes Start to first prompt Run duration
Developer 7,887 2.691 s 45.051 s
Tester 9,347 1.090 s 46.685 s
Reviewer 10,419 1.716 s 32.709 s

These are observed client byte counts and elapsed durations for this task, not provider token counts, billed cost, or proof of useful work at the first activity boundary. The source environment was used for live inference; wheel installation and interactive planning are separate checks. Reproduce from a checkout with an execution YAML containing the named manifest:

.venv/bin/python tools/acp_pipeline_probe.py --config /path/to/execution.yaml --local-agent codex

This opt-in command consumes provider usage, creates a new temporary repository, and keeps operator permissions explicit. Its validation commands are deliberately replaced by the synthetic task's Python unit tests.

A separate installed-wheel fixture run used a fresh isolated environment with the base wheel and no Ansible extra. The module resolved from site-packages. The public setup/preset commands and a synthetic ACP server completed the same three-role task, command checks, merge, cleanup and restart assertions. A separate installed dependency smoke confirmed idempotent setup and one SYSTEM resume with zero agent runs. This packaging evidence is distinct from the live Codex result above.

Authentication revalidation, 2026-09-07

Fresh evidence separates session creation, explicit authentication and inference. Existing installations and account settings were used; no provider or identity was selected implicitly.

Harness Fresh result Remaining prerequisite
Qwen 0.19.6 Only openai advertised; explicit authentication returned -32603 Installed method requires OPENAI_API_KEY, absent in the probe environment
Kimi 0.39.1 Session and explicit login returned -32000 Complete native login; doctor found no local configuration
Cline 3.0.61 Initial prompt required re-authentication; subsequent native login and live probes passed Resolved; use the local-backend configuration below for managed tasks
OpenHands 1.16.0 Local session returned -32000 Configure agent/model: installed local handler maps missing agent specification to this response
Gemini 0.49.0 Configured oauth-personal explicitly rejected Individual access through this client was discontinued; an applicable supported access method is required
Cursor 2026.06.15-18-00-12-6f5a2cf Native status reports cached login; explicit cursor_login timed out after 30 seconds Complete a valid Cursor login; the recorded ACP handler waited for browser authentication

Gemini's response agrees with the upstream individual-access announcement. It is not evidence of missing cached credentials. Cursor's documented ACP authentication sequence was attempted; a cached native login does not prove an ACP session works. No inference was requested in these auth checks except the separate synthetic Cline attempt. All probe processes exited during bounded cleanup.

Cancellation while permission is pending, 2026-09-07

Live cancellation evidence confirms Claude adapter 0.75.1 / SDK 0.3.257, Codex adapter 1.10.0 / CLI 0.153.4, and native Grok 1.0.13. The common supervisor task was cancelled after observing an unanswered permission. Every permission became cancelled, the requested write marker remained absent, and the process group exited. The probe supports this scenario with --cancel-while-pending; its fixture covers the same assertions.

Codex required an explicit escalated shell request; selecting read-only alone is not evidence that ordinary workspace writes ask for permission. Grok used explicit default permission mode. Claude emitted $/cancel_request, which the pinned SDK logged as method-not-found; required cleanup still passed. This scope proves local cancellation and cleanup, not provider billing cancellation, an ACP cancelled stop response, public CLI cancellation, or optional extension parity.

Declared role coverage, 2026-09-07

This table records live evidence, not restrictions on manifest role assignment. D = completed domain role with accepted typed result; C = synthetic live conversation through the public CLI, including restart and recall; P = only a synthetic DEVELOPER-bound permission test; U = no live domain-role proof; B = broader live campaign cannot proceed past the auth/configuration issue above. USER is a human role and SYSTEM actions are deterministic daemon work, so neither is a harness assignment. Generic lifecycle tests do not fill domain-role cells.

Role Codex Claude Grok Qwen Kimi Cline OpenHands Gemini Cursor
ARCHITECT-PLANNER C C C B B C B B B
ARCHITECT-REVIEWER D U D B B U B B B
DEVELOPER D P P B B D B B B
UI-DEVELOPER U U U B B U B B B
LIVE-DEVELOPER C C C B B C B B B
TECHNICAL-WRITER U U U B B U B B B
TESTER D D U B B D B B B
READER U U U B B U B B B
EXPLORER U U U B B U B B B
MAINTAINER U U U B B U B B B

D cells derive from the single-harness local preset and operator-assisted mixed pipeline, plus the two accepted Cline domain stages. P cells derive from permission approval and pending-permission cancellation above. This is deliberately narrower than all roles on all harnesses. G6 and overall modernization are accepted for the owner-selected Codex/Claude/Grok scope; other integrations are deferred.

The offline conversation acceptance case separately exercises all ten agent roles: two FIFO user turns share one daemon-owned ACP session, preserve streamed events, create no domain result and do not relaunch after an idle restart. All ten cases passed on the subprocess fixture. This confirms the common role-independent conversation mechanism, not live domain coverage; the matrix above is unchanged.

Public conversation restart and reconnect, 2026-09-07

Live evidence records six scenarios: ARCHITECT-PLANNER and LIVE-DEVELOPER on each tested Codex, Claude and Grok installation. The reproducible tool is tools/acp_conversation_probe.py: pass --config with a manifest file and --agent with its name. It creates a disposable project and uses public chat create, chat send, chat attach --after and separate coordd --once processes. It uses model usage and denies permissions.

Every first reply matched a random token. The next daemon process loaded the same ACP session and recalled that token, which the second prompt did not contain. Duplicate delivery of the second request ID created no extra turn. Cursor reads left the conversation journal unchanged and excluded the first turn's events. Both runs completed, their process groups exited, and an idle restart preserved runs, results and commands. No domain result was created.

The subprocess fixture verifies this orchestration and rejects a peer without loadSession. Live evidence is specific to synthetic conversations: it does not prove domain plan generation, live code editing, mid-turn crash recovery, streaming terminal detach, Quick Picks or vendor extensions. C cells therefore remain distinct from D cells. Deferred installations still need their recorded access or configuration issues resolved before their live campaign resumes.

Cursor authentication diagnosis, 2026-09-07

Read-only diagnosis matched the native debug log to the exact process recorded in the explicit-auth probe. It shows cursor_login returned a false login check, started browser authentication and waited for its result. Shared-service initialization and successful authentication were not reached before the deadline. The installed handler source confirms this sequence. No additional authentication or model request was sent for this diagnosis.

This narrows the earlier timeout to an unfinished login flow. Native status reporting cached login is insufficient for this ACP handler. The precise reason the cache failed validation remains unknown; credentials, account identities and authorization URLs were not exported. A valid completed native login is needed before repeating Cursor's session/model/worktree/cancellation scenarios.

Cline after native login, 2026-09-07

Fresh Cline 3.0.61 evidence confirms exact synthetic replies, model anthropic/claude-sonnet-5 and mode act selection, streaming cancellation with cancelled, and cancellation while a permission is pending without executing the requested write. Public CLI ARCHITECT-PLANNER and LIVE-DEVELOPER conversations both preserved the token after a daemon restart, used the same loaded session, deduplicated delivery, reconnected by event cursor and performed no new work on an idle restart. Process cleanup passed.

Cline advertises both provider and model selectors in category model. The common client previously selected the first entry and rejected the actual model. It now finds the unique selector advertising the requested value and rejects ambiguity before sending a configuration request. The explicit probe used the already configured provider/model; no global account or provider settings changed.

For managed Cline execution, use the native attached local backend explicitly:

agents:
  cline:
    transport: acp
    argv: [env, CLINE_SESSION_BACKEND_MODE=local, cline, --acp]
    adapter_version: native-3.0.61
    harness_version: 3.0.61

This is a fragment for coordination/execution.yaml; role bindings remain separate. env is a real executable in the argv array, and this non-secret setting affects only the launched process. Provider authentication stays in Cline's native settings. The backend option is documented in the Cline CLI reference and was verified in the installed executable. Its ACP session factory uses the backend selected by that environment variable. The default backend can reuse a shared Hub whose environment lacks the current Greatminds run credential. In the first task attempt, scoped contract inspection was correctly rejected for missing credentials; the run reached its permission deadline without an accepted result. The local backend preserved the scoped identity. No credential was added to model prompts, shell arguments, or configuration files. Local-backend conversation restart and both cancellation scenarios were also repeated successfully.

The local-backend domain test completed DEVELOPER and TESTER: both typed handoffs were applied, both daemon-owned test requests passed, and all six tests passed again independently in the task worktree. The reviewer returned -32603; one explicit retry returned the native diagnostic “Insufficient balance” for Cline Credits. That funding requirement is separate from the now-working login. No further model request was sent. This is a partial pipeline, not a completed review or merge. The task remains in feature_review, its worktree is preserved, main is unchanged, all recorded agent/command process groups exited, and another daemon process performed no additional work. Twenty-three inspected one-time approvals were consumed across these domain attempts; no persistent approval was granted. The raw balance and account data are excluded from the evidence file.