diff --git a/api/group-management.mdx b/api/group-management.mdx
index 0bfaa96..ee39d09 100644
--- a/api/group-management.mdx
+++ b/api/group-management.mdx
@@ -146,7 +146,7 @@ Each session has two databases in `data/v2-sessions/{agent_group_id}/{session_id
| Table | Purpose |
|-------|---------|
-| `messages_in` | Inbound messages, tasks, system notifications |
+| `messages_in` | Inbound messages, tasks, system notifications. A2A inbound rows carry `source_session_id` for reply return-path routing |
| `delivered` | Delivery tracking |
| `destinations` | Live destination map |
| `session_routing` | Default reply routing |
@@ -155,7 +155,7 @@ Each session has two databases in `data/v2-sessions/{agent_group_id}/{session_id
| Table | Purpose |
|-------|---------|
-| `messages_out` | Outbound messages |
+| `messages_out` | Outbound messages, including `in_reply_to` stamped by the agent's MCP tools for A2A reply correlation |
| `processing_ack` | Processing acknowledgments |
| `session_state` | Persistent key/value store |
| `container_state` | Tool-in-flight tracking |
diff --git a/api/message-routing.mdx b/api/message-routing.mdx
index 4578590..8934a13 100644
--- a/api/message-routing.mdx
+++ b/api/message-routing.mdx
@@ -86,11 +86,21 @@ For each session with due outbound messages:
2. Filter already-delivered via `inbound.db`'s `delivered` table
3. Route by `kind`:
- `system` — dispatch to registered delivery action handlers
- - `channel_type='agent'` — agent-to-agent module
+ - `channel_type='agent'` — agent-to-agent module (see [return-path routing](#agent-to-agent-return-path-routing))
- Normal — permission check, then channel adapter delivery
4. Mark delivered in `inbound.db`
5. Clean up `outbox/` files (best-effort)
+## Agent-to-agent return-path routing
+
+When an agent emits a reply to another agent group, the target may have multiple active sessions. The router resolves the destination session in three layers, highest fidelity first:
+
+1. **Direct return-path** — if the outbound carries `in_reply_to`, the router opens the source session's `inbound.db`, reads the triggering row's `source_session_id`, and routes to that session.
+2. **Peer-affinity fallback** — when `in_reply_to` is absent or doesn't resolve, the router uses the most recent A2A inbound from the same peer agent group whose `source_session_id` is non-null.
+3. **Legacy fallback** — newest active session for the target agent group (pre-migration compatibility).
+
+The `source_session_id` column on `messages_in` is stamped when an outbound A2A message is converted to the target's inbound row. The container's MCP `send_message` and `send_file` tools thread the current batch's `in_reply_to` onto every outbound row so the host can correlate replies back to the originating session.
+
### Delivery actions
Modules register handlers via `registerDeliveryAction(action, handler)`:
diff --git a/changelog/docs-updates.mdx b/changelog/docs-updates.mdx
index 3da553f..6edf58f 100644
--- a/changelog/docs-updates.mdx
+++ b/changelog/docs-updates.mdx
@@ -5,6 +5,15 @@ icon: "file-pen"
rss: true
---
+
+ Documented the agent-to-agent reply routing fix from [qwibitai/nanoclaw#2267](https://github.com/qwibitai/nanoclaw/pull/2267). When a target agent group has multiple active sessions, A2A replies now route back to the session that asked the question via the new `source_session_id` column on `messages_in` and `in_reply_to` threading on `messages_out`.
+
+ ## Updated
+ - **`api/message-routing.mdx`**: new "Agent-to-agent return-path routing" section covering the three-layer resolution (direct return-path, peer-affinity fallback, legacy newest-active-session fallback)
+ - **`concepts/architecture.mdx`**: `messages_in` schema note for `source_session_id`; module summary updated to describe origin-aware A2A routing
+ - **`api/group-management.mdx`**: session-database table notes for the new `source_session_id` and `in_reply_to` fields
+
+
Phase A of the v2 documentation sprint — bringing the pages every new user lands on into alignment with the v2 rewrite. All claims verified directly against upstream source (`src/db/schema.ts`, `src/types.ts`, `src/config.ts`, `container/Dockerfile`, `src/delivery.ts`) rather than upstream `docs/` (which includes a stale `architecture.md` draft and a `db-session.md` that omits the `container_state` table).
diff --git a/concepts/architecture.mdx b/concepts/architecture.mdx
index bc7f3f8..c11f846 100644
--- a/concepts/architecture.mdx
+++ b/concepts/architecture.mdx
@@ -117,7 +117,7 @@ The host sweep (`src/host-sweep.ts`) runs every 60 seconds:
**Session inbound.db** (host writes, container reads):
-- **messages_in** — inbound messages with status, `process_after`, recurrence, `series_id`, and trigger flag
+- **messages_in** — inbound messages with status, `process_after`, recurrence, `series_id`, trigger flag, and (for A2A inbound) `source_session_id` for return-path routing
- **delivered** — tracks delivery outcomes
- **destinations** — live destination map (channels and other agents)
- **session_routing** — default reply routing
@@ -135,7 +135,7 @@ Modules self-register via barrel imports and provide optional hooks into the rou
- **Permissions** — sender resolution, access gating, channel approval, sender approval
- **Scheduling** — task creation, pause/resume/cancel/update via delivery actions
-- **Agent-to-agent** — cross-agent message routing
+- **Agent-to-agent** — cross-agent message routing with origin-aware return paths so replies land in the session that asked the question, not just the target's newest active session
- **Approvals** — interactive question cards
- **Self-mod** — agent self-modification requests
- **Typing** — typing indicator management