docs(a2a): client exposures, URLs without queries, README/architecture

This commit is contained in:
EugeneTes
2026-10-08 14:42:18 +00:00
parent 1817272b73
commit 923a6e04ac
6 changed files with 59 additions and 6 deletions

View File

@@ -64,6 +64,10 @@ malformed task file is read as "no such task" (`TaskNotFound`) without a log lin
Without it: name from `A2A:Card:Name`, description from the first non-empty line of the workspace's `PERSONA.md`
(else `A2A:Card:Description`), and one generic `chat` skill.
The [client](#client) keeps its own files in the same directory: `agents.json` (the agents this workspace's assistant
may call, with their keys; see [agents.json](#agentsjson)) and `pending.json` (its watches of remote tasks; see
[Watches](#watches)).
`tasks/<taskId>.json`: one task per file (the SDK's `AgentTask` plus which caller owns it and its push configs),
written atomically (temp file, then rename) and read fresh on every request.
@@ -154,7 +158,11 @@ zone into its sessions (`docs/telegram-bot.md#a2a`); a host that embeds the libr
- reading `.volcanic/a2a/callers.json` — every caller's plaintext key — and editing it, i.e. minting itself (or
anyone) new keys or changing other callers' entries;
- writing `.volcanic/scheduler/jobs.json` or `.volcanic/triggers/triggers.json`, whose prompts later run in the
owner's **main** session — the one that has the calendar and the owner's history.
owner's **main** session — the one that has the calendar and the owner's history;
- with the [client](#client) on, forging `.volcanic/a2a/pending.json`: a record with an `undelivered` text runs as a
prompt in the owner's chat on the next restart or session start;
- editing `.volcanic/a2a/agents.json` to point an agent name somewhere else, so the owner's next `send` to that
name — message, attachments and the configured key — goes there (and reading the keys in it).
These are accepted v1 exposures: the owner chose plain files with no protection. Give A2A keys only to agents you
would trust with that workspace.
@@ -215,7 +223,8 @@ Off (the default), no session gets the tool, no watches are restored, and `/a2a`
Only the owner's own chats get the `a2a` tool: the Telegram host adds `A2AClientExtension` to each allowed chat's
session (target = the chat id), never host-wide. So the isolated sessions the server opens for inbound A2A callers
(untrusted) can't use the keys in `agents.json` to call other agents. The startup log shows
(untrusted) can't call other agents through the tool (their `bash` can still read the keys in `agents.json`; see
[Client security](#client-security)). The startup log shows
`A2A client: on, agents in each chat's .volcanic/a2a/agents.json, watches subscribe or poll` (or `push at <url>`).
### agents.json
@@ -350,8 +359,10 @@ configured subscribes instead. On shutdown the watches stop and their records st
Every outgoing message carries `metadata["volcanic.hops"]` = the session's inbound hop count + 1. The count comes from
the `a2a.inbound` event the server's per-session extension emits before each inbound prompt; a session with no inbound
A2A counts 0. A Volcanic server refuses a task over its `MaxHops` (3), which stops two assistants delegating to each
other forever. In Telegram only the owner's chats have the tool, so their messages always carry 1; the listener
matters for hosts that add the extension to sessions that also receive A2A.
other forever. In Telegram only the owner's chats have the tool, so their messages always carry 1 and the listener is
inactive: the remote side's `MaxHops` (or whatever guard a non-Volcanic remote has) is the only thing that bounds a
chain of agents delegating onwards. The listener matters for hosts that add the extension to
sessions that also receive A2A.
### Client configuration
@@ -372,6 +383,10 @@ ignores any configured value otherwise.
- **`agents.json` keys are plaintext in the workspace**, like `callers.json`: anything that reads the workspace (the
agent's `bash`, an inbound A2A caller's isolated session, a backup) can read them.
- **An inbound A2A caller's isolated session can tamper with the client's files** through `bash` in the shared
workspace: forge `pending.json` (an `undelivered` text runs as a prompt in the owner's chat on restart or session
start) or redirect an agent name in `agents.json` (the owner's next `send`, its attachments and the key go to the new
URL). Accepted v1 exposures, like `jobs.json` (see [Security](#security)).
- **The agent chooses where data goes.** It can edit `agents.json` like any workspace file, so it can add an agent with
any URL (including internal addresses; the client's HTTP has no private-range guard) and send it workspace files.
That is the same trust it already has through `bash` (`curl`), not a new boundary; treat the `a2a` tool accordingly.