Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
d05949d
feat(a2a): implement A2A transport and server bridge (Track 3)
MichielBugherJelli May 20, 2026
57f7b4d
build: regenerate lockfiles after A2A SDK dependency resolution
MichielBugherJelli May 20, 2026
ff37985
fix(a2a): address Copilot review feedback
MichielBugherJelli May 20, 2026
4f987e9
fix(a2a): add explicit Gson dependency to adcp-server
MichielBugherJelli May 20, 2026
ecb9233
fix(a2a): address round-3 Copilot review feedback
MichielBugherJelli May 20, 2026
dfda1a9
fix(a2a): address round-4 Copilot review feedback
MichielBugherJelli May 20, 2026
eac046b
fix(a2a): address round-5 Copilot review feedback
MichielBugherJelli May 20, 2026
3f6e170
fix(a2a): eliminate lock gap in writeTimeoutResponse and move extract…
MichielBugherJelli May 20, 2026
db167a3
fix(a2a): validate sanitized tool name is non-blank and reject non-st…
MichielBugherJelli May 20, 2026
9c3416e
fix(a2a): restrict synchronous-client latch guard to terminal task re…
MichielBugherJelli May 20, 2026
8869da0
fix(a2a): reject tab in tool names, normalize cache key header case, …
MichielBugherJelli May 20, 2026
d2f7b89
fix(a2a): reject tool names with control characters instead of silent…
MichielBugherJelli May 21, 2026
8fa61c1
fix(a2a): bump Jackson to 2.20.1, deterministic header normalization,…
MichielBugherJelli May 21, 2026
016afcf
fix(a2a): exclude protected headers from cache hash and remove unreac…
MichielBugherJelli May 21, 2026
eeb7f82
fix(a2a): remove unused imports from A2aCallerTest
MichielBugherJelli May 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Decisions made post-RFC that supersede or refine the merged text. The table belo
| D7 | `javax`/`jakarta` floor | **`jakarta` only**, Spring Boot 3.x floor. Single `adcp-spring-boot-starter` artifact, no compat starter, no community 2.7 port. Spring Boot 2.7 OSS support ended Nov 2025; anyone still on it has a vendor relationship. | Resolves RFC Open Question 6 in favor of option (a) |
| D8 | Mock-server CI deployment | **Sidecar via `npx adcp mock-server`.** GitHub Actions Node step installs a pinned `@adcp/sdk` version, backgrounds one mock-server per specialism on a port range, Java tests hit `localhost`. The pinned `@adcp/sdk` version is the conformance oracle — bumping it is a deliberate PR. Promote to a published Docker image if multi-specialism orchestration becomes unwieldy. | Specifies D5's deployment |
| D9 | MCP Java SDK | **`io.modelcontextprotocol.sdk:mcp-core:1.1.2` + `mcp-json-jackson2:1.1.2`** at the core (not the `mcp` bundle artifact, which pulls jackson3). Used by `adcp` (caller) and `adcp-server` (agent). The Spring AI MCP SDK was donated to the `modelcontextprotocol` org in Feb 2025 and rebranded as the official Java SDK; current `spring-ai-mcp-*` artifacts are now thin Spring Boot wrappers on top of it — no parallel implementation. **License: MIT** (compatible, flagged for foundation position). Both prototype questions closed in [`specs/mcp-prototype-findings.md`](specs/mcp-prototype-findings.md): (a) `HttpServletStreamableServerTransportProvider` in `mcp-core` is framework-neutral — no Jetty/Tomcat dep at compile time, adopter brings their own servlet container at runtime; (b) `mcp-json-jackson2` and `mcp-json-jackson3` are at identical 1.1.2 cadence with the same surface — we pin to jackson2 to match the rest of the SDK's Jackson tree. | Resolves RFC Open Question 2 |
| D10 | A2A pre-1.0 type strategy | **Keep A2A types in-tree until `a2aproject/a2a-java` cuts a stable ≥ 1.0.0 release**, then migrate to the upstream client in one shot and deprecate the in-tree fallback in the next minor. As of the latest check, `a2a-java` is at `1.0.0.Beta1` (Apr 2026) — package layout still churning, so we don't hard-depend on it yet. | RFC default for Open Question 3 |
| D10 | A2A pre-1.0 type strategy | **Depend directly on `a2aproject/a2a-java` at `1.0.0.CR1`**, skipping the in-tree fallback. CR1 (May 2026) shows a stable package layout — the Beta1→CR1 delta is bug fixes and dep bumps only, no API reshuffling. Pin to CR1 now; upgrade to `1.0.0` final (imminent) as a straight version bump. The original "keep types in-tree" plan is dropped: the in-tree fallback would have been throwaway code given how close 1.0 GA is. | RFC default for Open Question 3 |
| D11 | `TransitionGuard` narrowing protection | **Guards declare which spec edges they touch.** Conformance harness fails if a sandbox account's guards narrow any edge the storyboards exercise. Guards run after the spec edge check and can never relax a spec edge. | Resolves RFC Open Question 7 |
| D12 | Spring Security integration depth | **Recipes-only at v1.0.** No separate `adcp-spring-boot-starter-security` artifact. Auth models vary too much to pre-bake; recipes age better than autoconfig. Revisit if v0.3 design-partner feedback demands it. | RFC default for Open Question 5 |
| D13 | Reactor + Mutiny adapters | **At GA, not fast-follow.** `adcp-reactor` and `adcp-mutiny` both ship in v1.0. WebFlux shops left to wrap the sync API would own that complexity forever and we'd lose the canonical surface. | Confirms RFC §Async model |
Expand Down Expand Up @@ -168,7 +168,7 @@ Each track entry has:
| v0.1 alpha | M+2 | L0 surface compiles, storyboards green against reference mock-server in CI. Local Gradle artifacts only (per D6 — first Maven Central publish at v0.3). |
| v0.2 alpha | M+4 | L1: RFC 9421 signing/verification, AWS+GCP KMS providers (lazy-init, per-`adcp_use`), webhook signing |
| v0.3 alpha | M+6 | L2 + partial L3: account store, idempotency, async tasks, Spring Boot starter alpha. **First Maven Central publish** (per D6). |
| v0.4 beta | M+9 | Full L3: transition validators, webhook emission, `comply_test_controller`, A2A transport |
| v0.4 beta | M+9 | Full L3: transition validators, webhook emission, `comply_test_controller`, A2A transport (implemented on `a2a-java` `1.0.0.CR1`) |
| v1.0 GA | M+12 | L0–L3 parity, Reactor + Mutiny adapters, Kotlin co-release, Maven Central GA |

The RFC's M+12 target is the realistic line. Pre-committing M+9 and slipping is worse than committing M+12 and beating it. Slippage concentrates on: MCP Java SDK churn, RFC 9421 canonicalization edge cases, shared lifecycle YAML coordination, Spring Boot starter scope creep.
Expand Down Expand Up @@ -228,8 +228,8 @@ The RFC's M+12 target is the realistic line. Pre-committing M+9 and slipping is
**Scope:**

- **MCP:** depend on `io.modelcontextprotocol.sdk:mcp` pinned `1.1.2` (per D9). Used by both `adcp` (caller) and `adcp-server` (agent). Plan a deliberate 2.x migration PR ~6 months out (the 2.0 line removes sealed interfaces from message types, replaces `JsonSchema` with `Map`, flips the tool-input-validation default, removes server-transport builder methods). License is MIT — flagged for foundation position. Two open prototype questions land harness Week 1: whether the servlet-based streamable-HTTP server transport works without pulling Jetty/Tomcat, and whether `mcp-json-jackson2` is feature-equivalent to the Jackson 3 module.
- **A2A pre-1.0:** minimal SSE consumer + JSON-RPC framer in `adcp-server`. Default: keep types in-tree until `a2a-java` cuts its first stable release (≥ 1.0.0), then migrate in one shot (RFC Open Question 3).
- **A2A post-1.0:** swap transport to `a2aproject/a2a-java`; deprecate the in-tree fallback in the next minor.
- **A2A (implemented):** caller-side `A2aConnectionManager` + `A2aCaller` in `adcp`, plus server-side `A2aAgentExecutor` + `A2aServerBuilder` + `A2aServlet` in `adcp-server`, now ship on upstream `a2aproject/a2a-java` pinned `1.0.0.CR1` (per D10). No in-tree fallback ships.
- **A2A version bump path:** upgrade from `1.0.0.CR1` to `1.0.0` final is a straight version bump once the upstream GA tag is cut.
- HTTP transport on `java.net.http.HttpClient`. No third-party HTTP client in the core.
- Jackson `ObjectMapper` with `StreamReadConstraints` / `StreamWriteConstraints` widened to AdCP-shaped defaults (RFC §JSON).
- **No `*Async` mirror methods.** With JDK 21 as baseline, virtual threads make the sync API scale natively; the RFC's 12-method `*Async` mirror surface is dropped (see [Confirmed decisions](#confirmed-decisions)). Adopters who explicitly want `CompletableFuture` wrap individual calls themselves.
Expand All @@ -238,7 +238,7 @@ The RFC's M+12 target is the realistic line. Pre-committing M+9 and slipping is

**Depends on:** `codegen` for the request/response types.

**Milestone targets:** v0.1 needs MCP transport. v0.4 swaps in upstream `a2a-java` if its 1.0 has cut by then; otherwise the in-tree fallback ships at v1.0 with the swap-trigger documented.
**Milestone targets:** v0.1 needs MCP transport. v0.4 now has A2A transport implemented on upstream `a2a-java` `1.0.0.CR1`; moving to `1.0.0` final is a straight version bump.

---

Expand Down
39 changes: 27 additions & 12 deletions adcp-cli/gradle.lockfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,36 @@
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
com.ethlo.time:itu:1.10.3=runtimeClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-annotations:2.18.2=compileClasspath,testCompileClasspath
com.fasterxml.jackson.core:jackson-annotations:2.20=runtimeClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-core:2.18.2=compileClasspath,testCompileClasspath
com.fasterxml.jackson.core:jackson-core:2.20.1=runtimeClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-databind:2.18.2=compileClasspath,testCompileClasspath
com.fasterxml.jackson.core:jackson-databind:2.20.1=runtimeClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-annotations:2.20=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-core:2.20.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.core:jackson-databind:2.20.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.20.1=runtimeClasspath,testRuntimeClasspath
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.18.2=compileClasspath,testCompileClasspath
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.20.1=runtimeClasspath,testRuntimeClasspath
com.fasterxml.jackson:jackson-bom:2.18.2=compileClasspath,testCompileClasspath
com.fasterxml.jackson:jackson-bom:2.20.1=runtimeClasspath,testRuntimeClasspath
com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.20.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.fasterxml.jackson:jackson-bom:2.20.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.api.grpc:proto-google-common-protos:2.66.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.code.findbugs:jsr305:3.0.2=runtimeClasspath,testRuntimeClasspath
com.google.code.gson:gson:2.14.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.errorprone:error_prone_annotations:2.48.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.protobuf:protobuf-java-util:4.33.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.google.protobuf:protobuf-java:4.33.2=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
com.networknt:json-schema-validator:1.5.6=runtimeClasspath,testRuntimeClasspath
io.modelcontextprotocol.sdk:mcp-core:1.1.2=runtimeClasspath,testRuntimeClasspath
io.modelcontextprotocol.sdk:mcp-json-jackson2:1.1.2=runtimeClasspath,testRuntimeClasspath
io.projectreactor:reactor-core:3.7.0=runtimeClasspath,testRuntimeClasspath
jakarta.annotation:jakarta.annotation-api:3.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
jakarta.el:jakarta.el-api:6.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
jakarta.enterprise:jakarta.enterprise.cdi-api:4.1.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
jakarta.enterprise:jakarta.enterprise.lang-model:4.1.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
jakarta.inject:jakarta.inject-api:2.0.1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
jakarta.interceptor:jakarta.interceptor-api:2.2.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.a2aproject.sdk:a2a-java-sdk-client-transport-jsonrpc:1.0.0.CR1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.a2aproject.sdk:a2a-java-sdk-client-transport-spi:1.0.0.CR1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.a2aproject.sdk:a2a-java-sdk-client:1.0.0.CR1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.a2aproject.sdk:a2a-java-sdk-common:1.0.0.CR1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.a2aproject.sdk:a2a-java-sdk-http-client:1.0.0.CR1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.a2aproject.sdk:a2a-java-sdk-jsonrpc-common:1.0.0.CR1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.a2aproject.sdk:a2a-java-sdk-spec-grpc:1.0.0.CR1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.a2aproject.sdk:a2a-java-sdk-spec:1.0.0.CR1=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=compileClasspath,testCompileClasspath
org.jspecify:jspecify:1.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:5.11.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
Expand All @@ -28,7 +43,7 @@ org.junit.platform:junit-platform-launcher:1.11.4=testRuntimeClasspath
org.junit:junit-bom:5.11.4=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.opentest4j:opentest4j:1.3.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.reactivestreams:reactive-streams:1.0.4=runtimeClasspath,testRuntimeClasspath
org.slf4j:slf4j-api:2.0.16=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.slf4j:slf4j-simple:2.0.16=runtimeClasspath,testRuntimeClasspath
org.slf4j:slf4j-api:2.0.17=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
org.slf4j:slf4j-simple:2.0.17=runtimeClasspath,testRuntimeClasspath
org.yaml:snakeyaml:2.4=runtimeClasspath,testRuntimeClasspath
empty=annotationProcessor,testAnnotationProcessor
Loading
Loading