CSE Roadmap

Common tier · about 6 hours · 6 parts

Part 5 of 6 · 5 min read

Exercises

Easy

Easy 1: Run it and break it by hand (30 minutes)

In code/mini-a2a, run pytest -q, then python demo.py and python evaluate.py. Then open server.py, delete the line that checks the audience of a token, and run pytest -x -q.

Done when: you report the test count, name the first check that fails for your edit and the rule it comes from, and explain why a check about tokens failed and not one about tasks.

Hint

the audience check is in tokens.verify's caller in server.py; run python -c "import conformance; print(conformance.explain({'wrong_audience_accepted'}))" to see what the suite thinks.

Easy 2: Read a card like an attacker (30 minutes)

Take venue_card() and write the smallest edit to its text that would make a keyword router send more requests to it, without adding a skill. Then run card_diff between the old and new card.

Done when: you show the edit, say whether needs_review fired, and say in two sentences why a signature would not stop this edit if the agent's owner made it.

Hint

the router weights rare words; look at which words in the other cards are rare.

Easy 3: Draw the sequence (40 minutes)

On paper, draw the messages for a vague request that gets a question and then an answer, over JSON-RPC. Mark the task id, the state at each step, and which message creates the task.

Done when: your drawing matches the output of demo.py step 1 and 2, you mark where the context id is first assigned, and you say which message would be rejected if the client sent it after COMPLETED.

Hint

the task is created by the server, so the first message has no task id.

Medium

Medium 1: Close an escape (2 hours)

Write a conformance check for no_push_retry: a receiver that answers 503 twice and then 200, and the assertion that it eventually gets the event. Add it to conformance.py and update the prediction in mutants.py.

Done when: the check passes on the correct server and fails with the defect, python evaluate.py reports 25 of 26 caught, and the escape test in test_a2a.py is updated honestly.

Hint

look at PN1 for how a receiver is set up, and make a receiver function that counts attempts; the retry delays are virtual.

Medium 2: A fourth way to learn about completion (2 hours)

Add long-polling to the HTTP binding: GET /rest/tasks/{id}?wait=15 holds the request until the status changes or the wait ends. Add it to update_mechanisms().

Done when: your row has requests, bytes and lateness for the same 20-second job, you say where it sits among the five rows and why, and you list one thing the specification would need to say for two implementations to agree on it.

Hint

the server's subscribe already knows how to wait on a task; copy its loop.

Medium 3: Pass an authorization request upward (3 hours)

The concierge turns AUTH_REQUIRED from a downstream agent into FAILED. Make it relay the state and the link to its own caller, and carry the credential back to the downstream task when the person completes the flow.

Done when: a test shows the concierge task in AUTH_REQUIRED with the downstream link, then COMPLETED after the out-of-band callback; you state who the credential belongs to at each hop; and you list one way this design could leak the link to the wrong user.

Hint

the callback at /oob/callback is the only door the credential may enter; the concierge's task needs its own link, not the downstream one.

Hard

Hard 1: Interoperate with an official SDK (4 hours)

Run an official A2A SDK client or server against this code, over JSON-RPC or HTTP+JSON, through web.serve. (I did not run this, so your results are the ground truth.)

Done when: you list every interaction that failed at first, say for each whether the SDK or this code was wrong with a quotation from the specification, and say which of my "choices" in section 9 the SDK made differently.

Hint

use the card's supportedInterfaces to point the SDK at web.serve's port; the A2A-Version header is the first thing to check.

Hard 2: A real model behind the tool (4 hours)

Put a real model in front of the naive and careful wrappers, with the five situations written afresh by someone who did not write the wrappers. Run each 10 times. (I did not run this.)

Done when: you report success per situation per wrapper with the model's name and the date, compare with the scripted caller's table, and say which of its failures a real model recovered from by reading the text.

Hint

write the situations before you read any output, and use a fresh world per run.

Hard 3: Attack your own concierge (4 hours)

Write three agents that try to harm a concierge: one whose card claims everything, one whose artifact contains instructions, and one that answers with a redirect to a private address. Run each against the concierge with trust on and off. (I did not run this.)

Done when: you report for each attack whether it worked under each setting, show the log line that proves it, say which defence the user would have to supply because the protocol cannot, and add one new check to the suite.

Hint

the guarded fetch is in net.py; the injection text is the INJECTION constant in executors.py.