Skip to content

Commit ab77fd0

Browse files
authored
docs: Add skill to fix TCK errors (a2aproject#735)
1 parent 4cf9867 commit ab77fd0

1 file changed

Lines changed: 323 additions & 0 deletions

File tree

Lines changed: 323 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,323 @@
1+
---
2+
name: fix-tck-issue
3+
description: Analyzes and fixes A2A Transport Compatibility Kit (TCK) issues by understanding the specification, reproducing the failure, implementing the fix, and validating it works.
4+
compatibility: Requires gh CLI and mvn
5+
allowed-tools: Bash(gh:*) Bash(mvn:*) Bash(git:*) Bash(curl:*) Read Edit Write Glob Grep WebFetch
6+
---
7+
8+
# Fix A2A TCK Compatibility Issue
9+
10+
## Triggers
11+
- Issue references TCK, compatibility, or transport-specific behavior
12+
- Keywords: "TCK", "compatibility", "HTTP+JSON", "gRPC", "JSON-RPC", "specification", "proto"
13+
- Issue mentions transport layer discrepancies
14+
15+
## Input
16+
- Issue number from a2aproject/a2a-java repository
17+
- Optional: A2A spec reference (branch/tag/commit, defaults to `main`)
18+
19+
## Workflow
20+
21+
### 1. Fetch Issue Details
22+
```bash
23+
gh issue view <issue-number> --repo a2aproject/a2a-java --json title,body,labels,url
24+
```
25+
26+
Parse issue to identify:
27+
- Affected transport(s): HTTP+JSON, gRPC, JSON-RPC
28+
- Expected behavior from specification
29+
- Actual behavior (error message, reproducer)
30+
- Specification section references
31+
- **Spec commit checksum** (TCK issues include this in spec URLs)
32+
33+
### 2. Read Specification (if needed)
34+
TCK issues contain the spec checksum, but reading the spec is helpful if TCK lags behind or for additional context.
35+
36+
Fetch from https://github.com/a2aproject/A2A with specified ref (use checksum from issue or default to main):
37+
- `specification/grpc/a2a.proto` - for proto definitions and HTTP transcoding
38+
- `docs/specification.md` - for detailed protocol requirements
39+
40+
Focus on sections referenced in the issue.
41+
42+
### 3. Analyze Code
43+
Locate relevant code based on transport:
44+
- **HTTP+JSON**: `transport/rest`
45+
- **gRPC**: `transport/grpc`
46+
- **JSON-RPC**: `transport/jsonrpc`
47+
48+
Identify root cause by comparing:
49+
- What the spec says should happen
50+
- What the code currently does
51+
- Why they differ
52+
53+
**Optional**: If issue includes a curl/grpcurl reproducer, run it manually to validate the issue is genuine.
54+
55+
### 4. Determine Affected Transports
56+
**CRITICAL**: If issue doesn't specify a single transport, you MUST create reproducers for ALL affected transports.
57+
58+
Issue mentions specific transport → Test that one only
59+
Issue generic or mentions "all transports" → Test HTTP+JSON, gRPC, AND JSON-RPC
60+
61+
### 5. Create Temporary Reproducer(s)
62+
Create test in appropriate module. Choose location based on test complexity:
63+
64+
**Option A: transport/* modules (Unit Tests)** - Use when:
65+
- Testing handler logic directly
66+
- Need custom AgentCard configuration (e.g., capability flags)
67+
- Simpler to set up specific test conditions
68+
- **HTTP+JSON**`transport/rest/src/test/java/io/a2a/transport/rest/handler/RestHandlerTest.java`
69+
- **gRPC**`transport/grpc/src/test/java/io/a2a/transport/grpc/handler/GrpcHandlerTest.java`
70+
- **JSON-RPC**`transport/jsonrpc/src/test/java/io/a2a/transport/jsonrpc/handler/JSONRPCHandlerTest.java`
71+
72+
**Option B: reference/* modules (Integration Tests)** - Use when:
73+
- Testing full request/response cycle
74+
- Need real server behavior
75+
- Testing with standard agent configuration
76+
- **HTTP+JSON**`reference/rest/src/test/java/.../`
77+
- **gRPC**`reference/grpc/src/test/java/.../`
78+
- **JSON-RPC**`reference/jsonrpc/src/test/java/.../`
79+
80+
Reproducer requirements:
81+
- Follow the exact scenario from the issue
82+
- Use request format per specification (e.g., NO taskId in body for HTTP+JSON)
83+
- Be named clearly: `test_Issue<number>_Reproducer()`
84+
- Assert the WRONG behavior that issue reports (should fail)
85+
86+
Example:
87+
```java
88+
@Test
89+
public void test_Issue732_Reproducer() {
90+
// Per spec: taskId should NOT be in request body for HTTP+JSON
91+
String requestBody = """
92+
{
93+
"id": "my-config-001",
94+
"url": "https://example.com/webhook"
95+
}""";
96+
97+
HTTPRestResponse response = handler.createTaskPushNotificationConfiguration(
98+
context, "", requestBody, taskId);
99+
100+
assertEquals(201, response.getStatusCode());
101+
}
102+
```
103+
104+
### 6. Run Reproducer(s) - Confirm Failure
105+
**CRITICAL**: You MUST run the reproducer and see it FAIL before proceeding to fix.
106+
107+
For transport/* modules:
108+
```bash
109+
mvn test -Dtest=<TestClass>#test_Issue<number>_Reproducer -pl transport/<transport>
110+
```
111+
112+
For reference/* modules:
113+
```bash
114+
mvn test -Dtest=<TestClass>#test_Issue<number>_Reproducer -pl reference/<transport>
115+
```
116+
117+
**Required verification (DO NOT SKIP)**:
118+
- ❌ Test MUST fail with the exact error mentioned in the issue
119+
- ❌ Error message, status code, or exception type MUST match issue description
120+
- ❌ If testing multiple transports, ALL reproducers must fail
121+
122+
**If reproducer doesn't fail as expected**:
123+
- STOP - Do not proceed to fix
124+
- Reassess understanding of the issue
125+
- Check if test conditions match issue scenario
126+
- Verify you're testing the right transport/endpoint
127+
128+
**Only proceed to step 7 after confirming all reproducers fail correctly.**
129+
130+
### 7. Implement Fix
131+
Make minimal code changes to fix the root cause.
132+
133+
**If multiple transports are affected**: Fix ALL of them before proceeding to verification.
134+
135+
Common patterns:
136+
- **Missing path parameter extraction**: Add `builder.setFieldName(pathParam)`
137+
- **Wrong validation**: Adjust validation logic to match spec
138+
- **Incorrect mapping**: Fix proto/domain conversion
139+
- **Wrong error type**: Return correct error based on failure reason
140+
141+
### 8. Run Reproducer(s) - Confirm Fix
142+
Run ALL reproducers you created in step 5.
143+
144+
For transport/* modules:
145+
```bash
146+
mvn test -Dtest=<TestClass>#test_Issue<number>_Reproducer -pl transport/<transport>
147+
```
148+
149+
For reference/* modules:
150+
```bash
151+
mvn test -Dtest=<TestClass>#test_Issue<number>_Reproducer -pl reference/<transport>
152+
```
153+
154+
**Required verification**:
155+
- ✅ ALL reproducers must now PASS
156+
- ✅ Test output shows expected behavior (correct status, no error, etc.)
157+
158+
If any reproducer still fails, debug and refine the fix.
159+
160+
### 9. Verify Backward Compatibility
161+
Run full test suite for ALL modified transport modules to ensure no regressions:
162+
163+
```bash
164+
mvn test -pl transport/rest,transport/jsonrpc,transport/grpc
165+
```
166+
167+
If you also modified reference modules or only created reproducers there:
168+
```bash
169+
mvn test -pl reference/rest,reference/jsonrpc,reference/grpc
170+
```
171+
172+
All existing tests must pass.
173+
174+
### 10. Delete Temporary Reproducer(s)
175+
Remove ALL test methods or files created in step 5.
176+
177+
If you added a method to existing test class:
178+
- Delete just the `test_Issue<number>_Reproducer()` method
179+
180+
If you created a new test file:
181+
- Delete the entire file (e.g., `Issue733ReproducerTest.java`)
182+
183+
### 11. Commit
184+
Add only the impacted files (NOT the temporary reproducers):
185+
```bash
186+
git add <changed-files>
187+
git commit -m "fix: <concise description>
188+
189+
<explanation of spec requirement and how code was fixed>
190+
191+
Applied to <list transports if multiple>.
192+
193+
Fixes #<issue-number>"
194+
```
195+
196+
Example for multi-transport fix:
197+
```bash
198+
git add transport/rest/src/main/java/io/a2a/transport/rest/handler/RestHandler.java \
199+
transport/jsonrpc/src/main/java/io/a2a/transport/jsonrpc/handler/JSONRPCHandler.java \
200+
transport/grpc/src/main/java/io/a2a/transport/grpc/handler/GrpcHandler.java
201+
git commit -m "fix: Return UnsupportedOperationError when capability is disabled
202+
203+
Applied to all three transports: HTTP+JSON, JSON-RPC, and gRPC.
204+
205+
Fixes #733"
206+
```
207+
208+
## Common Root Causes
209+
210+
### HTTP+JSON with `body: "*"`
211+
Proto definition with path parameters and `body: "*"` means:
212+
- Path parameters extracted from URL
213+
- Body contains remaining fields only
214+
- Handler must set path params into builder
215+
216+
Example proto:
217+
```protobuf
218+
rpc CreateTaskPushNotificationConfig(...) {
219+
option (google.api.http) = {
220+
post: "/tasks/{task_id}/pushNotificationConfigs"
221+
body: "*"
222+
};
223+
}
224+
```
225+
226+
Fix pattern:
227+
```java
228+
// Extract from URL path and set in builder
229+
builder.setTaskId(taskId);
230+
```
231+
232+
### Field Validation Errors
233+
"X is required" errors often mean:
234+
- Field should come from URL path, not body
235+
- Handler isn't setting the path parameter
236+
- Check proto's HTTP annotation
237+
238+
## Test Location Decision Guide
239+
240+
### transport/* modules (Unit Tests)
241+
**Best for**:
242+
- Testing handler logic with custom configurations
243+
- Issues requiring specific AgentCard capabilities (e.g., streaming=false, extendedAgentCard=false)
244+
- Faster test execution
245+
- More control over test setup
246+
247+
**Test file locations**:
248+
- `transport/rest/src/test/java/io/a2a/transport/rest/handler/RestHandlerTest.java`
249+
- `transport/grpc/src/test/java/io/a2a/transport/grpc/handler/GrpcHandlerTest.java`
250+
- `transport/jsonrpc/src/test/java/io/a2a/transport/jsonrpc/handler/JSONRPCHandlerTest.java`
251+
252+
### reference/* modules (Integration Tests)
253+
**Best for**:
254+
- Testing full request/response cycles
255+
- Issues related to server behavior
256+
- Testing with standard agent configuration
257+
- Real-world scenario validation
258+
259+
**Structure**:
260+
```
261+
reference/
262+
├── rest/ # HTTP+JSON integration tests
263+
├── grpc/ # gRPC integration tests
264+
└── jsonrpc/ # JSON-RPC integration tests
265+
```
266+
267+
## Examples
268+
269+
### Example 1: Single Transport Issue
270+
Issue #732: CreateTaskPushNotificationConfig required taskId in body (HTTP+JSON only)
271+
272+
1. ✅ Fetched issue - HTTP+JSON transport, expects taskId from URL
273+
- Issue references spec @ `0833a5f5fd1b715519c0aecf9e3055e3f9f38089`
274+
2. ✅ Read spec - `body: "*"` means taskId from path
275+
3. ✅ Found root cause - RestHandler wasn't setting taskId from path param
276+
4. ✅ Issue specifies HTTP+JSON only - test only that transport
277+
5. ✅ Created reproducer in reference/rest without taskId in body
278+
6. ✅ **Ran reproducer - CONFIRMED FAILURE with 422 status**
279+
7. ✅ Fixed - added `builder.setTaskId(taskId)` to RestHandler
280+
8. ✅ **Ran reproducer - CONFIRMED PASS**
281+
9. ✅ Ran full test suite - all tests pass
282+
10. ✅ Deleted reproducer
283+
11. ✅ Committed (RestHandler.java only)
284+
285+
### Example 2: Multi-Transport Issue
286+
Issue #733: GetExtendedAgentCard returns wrong error when capability disabled
287+
288+
1. ✅ Fetched issue - affects all transports (not specified which)
289+
- Issue references spec @ `0833a5f5fd1b715519c0aecf9e3055e3f9f38089`
290+
2. ✅ Read spec - should return UnsupportedOperationError when capability=false
291+
3. ✅ Found root cause - handlers check config before capability
292+
4. ✅ **Issue affects all transports - must test all three**
293+
5. ✅ Created reproducers in transport/rest, transport/jsonrpc, transport/grpc
294+
6. ✅ **Ran all reproducers - CONFIRMED all fail (wrong error type)**
295+
7. ✅ Fixed all three handlers - check capability before config
296+
8. ✅ **Ran all reproducers - CONFIRMED all pass**
297+
9. ✅ Ran full test suite - all tests pass
298+
10. ✅ Deleted all three reproducers
299+
11. ✅ Committed (all three handler files)
300+
301+
## Critical Success Factors
302+
303+
### Must Do
304+
- ✅ **ALWAYS run reproducer BEFORE fixing** - Confirms you understand the issue
305+
- ✅ **Test ALL affected transports** - Don't assume single transport unless issue specifies
306+
- ✅ **Confirm exact failure** - Error type, status code, message must match issue
307+
- ✅ **Verify fix with reproducers** - All must pass before proceeding
308+
- ✅ **Delete all reproducers** - Keep test suites clean
309+
310+
### Best Practices
311+
- a2a.proto and spec are source of truth for compatibility
312+
- Reproducers prove understanding before fixing
313+
- Minimal, targeted fixes are better than broad changes
314+
- Choose test location (transport/* vs reference/*) based on requirements
315+
- Run full test suite to ensure no regressions
316+
- Commit only code changes, never temporary reproducers
317+
318+
### Common Pitfalls
319+
- ❌ Fixing without running reproducer first
320+
- ❌ Testing only one transport when issue affects multiple
321+
- ❌ Not confirming exact error before proceeding
322+
- ❌ Committing temporary reproducer tests
323+
- ❌ Skipping backward compatibility verification

0 commit comments

Comments
 (0)