You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The agent-client-protocol Rust SDK (https://github.com/agentclientprotocol/rust-sdk) released crate major version 2.0.0 on 2026-07-23. Zeph currently pins agent-client-protocol = "1.2.0" / agent-client-protocol-schema = "=1.4.0" in the root Cargo.toml. This issue tracks migrating crates/zeph-acp to the 2.0.0 line.
Important scope clarification (verified during spec research, see below): "ACP v2" here means the crate's major version 2.0.0 — an in-process Rust API redesign — not a wire-protocol v2. The wire protocol Zeph speaks stays at V1 throughout this migration; existing IDE hosts negotiate identically before and after. This is a dependency-major migration, not a protocol renegotiation. (A distinct, still-gated unstable_protocol_v2 wire-level draft exists upstream and is tracked separately in the spec's "Future/v2 Tracking" section — out of scope here.)
Spec
Full migration plan, invariants, and acceptance criteria: specs/013-acp/spec.md (v1.10, merged via PR #6654):
New "Breaking Changes Resolution (SDK 1.2.0 → 2.0.0)" table
Related/superseded tracking issue: #4461 (speculative wire-v2 tracking issue predating this release; its specific predictions did not materialize — see comment there).
Scope — contained entirely in crates/zeph-acp/
Grep-confirmed: the root binary (src/acp.rs) only uses zeph_acp::* wrappers, never SDK types directly. All affected usage sites are inside crates/zeph-acp/src/ (agent/, client/, custom.rs, error.rs, fs.rs, lsp/, mcp_bridge.rs, permission.rs, terminal.rs, transport/).
Breaking changes in 2.0.0 relevant to Zeph
Renamed/removed (grep-confirmed zero current usage of any of these in crates/zeph-acp/src — no action needed, listed for completeness):
Native unstable_mcp_over_acp (McpServer::Acp, mcp/connect) — replaces removed SDK-local McpAcpTransport/McpConnect* types. Zeph's mcp_bridge.rs already has a _ => warn!+None catch-all, so a McpServer::Acp variant from a host falls through cleanly; Zeph does not enable this feature, so hosts shouldn't send it anyway.
Named compiler-verify points (need confirmation at bump time, not assumed clean):
ActiveSession::connection() now returns &ConnectionTo<_> (used at client/driver.rs:149/204/259 via .connection().send_notification)
Option<&T> borrow-return changes on modes/meta/id accessors
Dispatch<Req,Notif> new Notif: JsonRpcNotification bound (agent/handlers/dispatch.rs:39)
Behavioral changes (live-test-only, not caught by unit tests):
Ordered-response-callback barrier now enforced in 2.0 (historically the class of issue behind the feat(llm): Claude server-side compaction API (compact-2026-01-12 beta) #1696 cascade — Zeph registers no on_receiving_result callbacks and its block_task calls sit inside request handlers, so expected-fine, but must be verified live)
Standard transports now accept JSON-RPC batches (Zeph gets this for free; verify streaming stays intact)
Dropping a Responder for one request now emits an Internal-Error fallback after dispatch (benign for Zeph — prompt.rs:34/dispatch.rs:28 always call responder.respond(...) on every handled path — but verify no unexpected Internal-Error frames appear in the live test)
Migration steps (from spec Addendum)
Bump root Cargo.toml: agent-client-protocol = "2.0.0"; run cargo update + cargo tree to determine which schema version (1.5.0 or 1.6.0 line) 2.0.0 actually resolves, and =-pin to that exact version.
PRE-MERGE WIRE GATE (blocking) — confirm ProtocolVersion::LATEST.as_u16() == 1 under the resolved schema with Zeph's feature set (unstable_protocol_v2 OFF). Add a local literal assert_eq!(ProtocolVersion::LATEST.as_u16(), 1) regression guard. If this resolves to 2, STOP — re-classify as a wire-breaking change requiring dual-version/negotiation handling, not a mechanical bump, and return to the architecture stage.
cargo check -p zeph-acp --features full — triage and fix the three named compiler-verify points above mechanically.
Build zeph-acp under each unstable feature individually, plus acp-http — cfg-gated code is invisible to the default build (a previously-documented trap from the 1.4.0 migration).
Full CI suite: cargo +nightly fmt --check, cargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warnings, cargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins, rustdoc gate.
Mandatory live round-trip gate (LLM-serialization gate, per .claude/rules/branching.md — this touches the ACP request/response path): initialize → prompt → tool call exercising AcpPermissionGate.block_task → set_config_option{model} → set_mode → fork → resume → session/delete → logout. Assert: no 400/422 errors, no deadlock, streaming intact, both stdio and (if enabled) http/ws transports. Explicitly assert /agent.json and /.well-known/acp.json emit literal protocol_version: 1 — not just "no error".
Update specs/013-acp/spec.md Implementation Gap Tracker entry I23 to reflect completion, and CHANGELOG.md.
Open questions (need a decision during implementation, not blocking spec merge)
Adopt native unstable_mcp_over_acp now, or keep passthrough behavior and defer? Recommendation: defer — matches the existing spec's MCP-over-ACP deferral stance.
Exact schema pin: =1.5.0 (built-against) vs =1.6.0 (latest, also confirmed wire-V1-safe)? Recommendation: pin to whatever cargo tree shows agent-client-protocol 2.0.0 actually resolves.
Pure mechanical bump vs. adopting new 2.x surface (batch framing, unstable_protocol_v2 draft) in the same pass? Recommendation: mechanical only — matches the clean-bump precedent set by the prior 0.14.0 and 1.0.1 migrations; adopting new surface is a separate follow-up.
Risks
Compile: LOW — migration surface is barely touched; only the three named compiler-verify points need confirmation.
Behavioral: MEDIUM — the three behavioral changes above are live-test-only; not caught by the unit/integration suite.
Pin exactness — if 2.0.0 resolves via a caret range, cargo update could later pull a newer schema than tested; the = pin must match exactly what was tested.
Interop/rollout: LOW, conditional on the wire gate passing — no wire-schema break is expected (verified via upstream agent-client-protocol-schema source: ProtocolVersion::LATEST is cfg-gated to V1 and is not even a valid symbol when unstable_protocol_v2 is enabled, so Zeph cannot accidentally advertise wire v2). This is why a big-bang cutover (no dual-version support) is the recommended approach — but step 2's gate must still be run and pass before merge.
Run /rust-agents:team-develop with the refactoring chain (dependency-major migration, no architect needed — this issue and specs/013-acp/spec.md already contain the full plan) on this issue. The developer should start from the spec's Addendum "Version Upgrade Note (1.2.0 → 2.0.0)" step list.
Description
The
agent-client-protocolRust SDK (https://github.com/agentclientprotocol/rust-sdk) released crate major version2.0.0on 2026-07-23. Zeph currently pinsagent-client-protocol = "1.2.0"/agent-client-protocol-schema = "=1.4.0"in the rootCargo.toml. This issue tracks migratingcrates/zeph-acpto the 2.0.0 line.Important scope clarification (verified during spec research, see below): "ACP v2" here means the crate's major version 2.0.0 — an in-process Rust API redesign — not a wire-protocol v2. The wire protocol Zeph speaks stays at
V1throughout this migration; existing IDE hosts negotiate identically before and after. This is a dependency-major migration, not a protocol renegotiation. (A distinct, still-gatedunstable_protocol_v2wire-level draft exists upstream and is tracked separately in the spec's "Future/v2 Tracking" section — out of scope here.)Spec
Full migration plan, invariants, and acceptance criteria:
specs/013-acp/spec.md(v1.10, merged via PR #6654):unstable_protocol_v2is deliberately not forwardedRelated/superseded tracking issue: #4461 (speculative wire-v2 tracking issue predating this release; its specific predictions did not materialize — see comment there).
Scope — contained entirely in
crates/zeph-acp/Grep-confirmed: the root binary (
src/acp.rs) only useszeph_acp::*wrappers, never SDK types directly. All affected usage sites are insidecrates/zeph-acp/src/(agent/,client/,custom.rs,error.rs,fs.rs,lsp/,mcp_bridge.rs,permission.rs,terminal.rs,transport/).Breaking changes in 2.0.0 relevant to Zeph
Renamed/removed (grep-confirmed zero current usage of any of these in
crates/zeph-acp/src— no action needed, listed for completeness):ResponseRouter::respond_*→route_*Builder::with_responder→with_runnerMatchDispatch::if_message→if_dispatchrun_indefinitely→detachTypeNotification,send_error_notification,respond_with_error,DynamicHandler*,attach_session,util::both,process_stream_concurrentlyAdded (not adopted in this migration — deferred):
AcpAgent/AcpAgentConfig,TransportFrame/batch framing,DynamicHandlerGuardunstable_mcp_over_acp(McpServer::Acp,mcp/connect) — replaces removed SDK-localMcpAcpTransport/McpConnect*types. Zeph'smcp_bridge.rsalready has a_ => warn!+Nonecatch-all, so aMcpServer::Acpvariant from a host falls through cleanly; Zeph does not enable this feature, so hosts shouldn't send it anyway.Named compiler-verify points (need confirmation at bump time, not assumed clean):
ActiveSession::connection()now returns&ConnectionTo<_>(used atclient/driver.rs:149/204/259via.connection().send_notification)Option<&T>borrow-return changes onmodes/meta/idaccessorsDispatch<Req,Notif>newNotif: JsonRpcNotificationbound (agent/handlers/dispatch.rs:39)Behavioral changes (live-test-only, not caught by unit tests):
on_receiving_resultcallbacks and itsblock_taskcalls sit inside request handlers, so expected-fine, but must be verified live)Responderfor one request now emits an Internal-Error fallback after dispatch (benign for Zeph —prompt.rs:34/dispatch.rs:28always callresponder.respond(...)on every handled path — but verify no unexpected Internal-Error frames appear in the live test)Migration steps (from spec Addendum)
Cargo.toml:agent-client-protocol = "2.0.0"; runcargo update+cargo treeto determine which schema version (1.5.0 or 1.6.0 line) 2.0.0 actually resolves, and=-pin to that exact version.ProtocolVersion::LATEST.as_u16() == 1under the resolved schema with Zeph's feature set (unstable_protocol_v2OFF). Add a local literalassert_eq!(ProtocolVersion::LATEST.as_u16(), 1)regression guard. If this resolves to2, STOP — re-classify as a wire-breaking change requiring dual-version/negotiation handling, not a mechanical bump, and return to the architecture stage.cargo check -p zeph-acp --features full— triage and fix the three named compiler-verify points above mechanically.zeph-acpunder each unstable feature individually, plusacp-http— cfg-gated code is invisible to the default build (a previously-documented trap from the 1.4.0 migration).cargo +nightly fmt --check,cargo clippy --profile ci --workspace --all-targets --features "desktop,ide,server,chat,pdf,scheduler,testing" -- -D warnings,cargo nextest run --config-file .github/nextest.toml --workspace --features "desktop,ide,server,chat,pdf,scheduler" --lib --bins, rustdoc gate..claude/rules/branching.md— this touches the ACP request/response path):initialize→prompt→ tool call exercisingAcpPermissionGate.block_task→set_config_option{model}→set_mode→fork→resume→session/delete→logout. Assert: no 400/422 errors, no deadlock, streaming intact, both stdio and (if enabled) http/ws transports. Explicitly assert/agent.jsonand/.well-known/acp.jsonemit literalprotocol_version: 1— not just "no error".specs/013-acp/spec.mdImplementation Gap Tracker entry I23 to reflect completion, andCHANGELOG.md.Open questions (need a decision during implementation, not blocking spec merge)
unstable_mcp_over_acpnow, or keep passthrough behavior and defer? Recommendation: defer — matches the existing spec's MCP-over-ACP deferral stance.=1.5.0(built-against) vs=1.6.0(latest, also confirmed wire-V1-safe)? Recommendation: pin to whatevercargo treeshowsagent-client-protocol 2.0.0actually resolves.unstable_protocol_v2draft) in the same pass? Recommendation: mechanical only — matches the clean-bump precedent set by the prior 0.14.0 and 1.0.1 migrations; adopting new surface is a separate follow-up.Risks
2.0.0resolves via a caret range,cargo updatecould later pull a newer schema than tested; the=pin must match exactly what was tested.agent-client-protocol-schemasource:ProtocolVersion::LATESTis cfg-gated toV1and is not even a valid symbol whenunstable_protocol_v2is enabled, so Zeph cannot accidentally advertise wire v2). This is why a big-bang cutover (no dual-version support) is the recommended approach — but step 2's gate must still be run and pass before merge.Environment
agent-client-protocol = "1.2.0",agent-client-protocol-schema = "=1.4.0"(rootCargo.toml:21-22)agent-client-protocol = "2.0.0", schema pin TBD (=1.5.0or=1.6.0, resolved viacargo treeat implementation time)zeph-acp(feature flags:unstable-session-fork,unstable-session-usage,unstable-elicitation,unstable-llm-providers,unstable-auth-methods)Suggested next step
Run
/rust-agents:team-developwith therefactoringchain (dependency-major migration, no architect needed — this issue andspecs/013-acp/spec.mdalready contain the full plan) on this issue. The developer should start from the spec's Addendum "Version Upgrade Note (1.2.0 → 2.0.0)" step list.