fix(a2a): reject delegate_task to your own workspace ID (self-deadlock guard) #291

Merged
claude-ceo-assistant merged 1 commits from fix/self-delegation-guard into main 2026-05-10 10:53:19 +00:00
Owner

Self-delegation (delegate_task to your own workspace ID) deadlocks _run_lock — the sending turn holds it, the receive handler waits for it, the request 30s-times-out, the cycle is wasted. The Dev Lead system prompt warns agents off this by hand; there was no platform/runtime guard.

Change

tool_delegate_task + tool_delegate_task_async early-return an actionable error when workspace_id == effective_source (source_workspace_id or _peer_to_source[target] or WORKSPACE_ID) — placed before discover_peer, so no network round-trip is wasted. A genuinely different target (including another of a multi-workspace agent's own registered workspaces) is unaffected.

Tests

tests/test_a2a_tools_delegation.py — new TestSelfDelegationGuard (rejects own ID; rejects when source_workspace_id explicitly == target; async path rejects; different target passes through to discover_peer). pytest tests/test_a2a_tools_delegation.py12 passed. (Note: test_a2a_tools_impl.py's TestToolDelegateTask* suite is red on this PC2/Windows checkout — same on main without this change, an httpx-mock infra issue, not this PR — CI on Linux validates.)

Deploys with the runtime wheel (i.e. via internal#214 once that's unblocked by #289). Closes the _run_lock self-deadlock footgun.

🤖 Generated with Claude Code

Self-delegation (`delegate_task` to your own workspace ID) deadlocks `_run_lock` — the sending turn holds it, the receive handler waits for it, the request 30s-times-out, the cycle is wasted. The Dev Lead system prompt warns agents off this by hand; there was no platform/runtime guard. ### Change `tool_delegate_task` + `tool_delegate_task_async` early-return an actionable error when `workspace_id == effective_source` (`source_workspace_id or _peer_to_source[target] or WORKSPACE_ID`) — placed **before `discover_peer`**, so no network round-trip is wasted. A genuinely different target (including another of a multi-workspace agent's own registered workspaces) is unaffected. ### Tests `tests/test_a2a_tools_delegation.py` — new `TestSelfDelegationGuard` (rejects own ID; rejects when `source_workspace_id` explicitly == target; async path rejects; different target passes through to `discover_peer`). `pytest tests/test_a2a_tools_delegation.py` → **12 passed**. (Note: `test_a2a_tools_impl.py`'s `TestToolDelegateTask*` suite is red on this PC2/Windows checkout — same on `main` without this change, an httpx-mock infra issue, not this PR — CI on Linux validates.) Deploys with the runtime wheel (i.e. via internal#214 once that's unblocked by #289). Closes the `_run_lock` self-deadlock footgun. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hongming-pc2 added 1 commit 2026-05-10 10:47:02 +00:00
fix(a2a): reject delegate_task / delegate_task_async to your own workspace ID
Some checks failed
sop-tier-check / tier-check (pull_request) Failing after 9s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 10s
audit-force-merge / audit (pull_request) Successful in 5s
31ed137b74
Self-delegation deadlocks: the sending turn holds `_run_lock`, the receive
handler waits for the same lock, the A2A request 30s-times-out, and the
whole cycle is wasted (the Dev Lead system prompt warns agents off this by
hand — "Never delegate_task to your own workspace ID … there is no peer who
is also you"). The platform/runtime had no guard. Now both
`tool_delegate_task` and `tool_delegate_task_async` early-return an
actionable error when `workspace_id == effective_source` (`source_workspace_id
or _peer_to_source[target] or WORKSPACE_ID`) — before `discover_peer`, so no
network round-trip is wasted either. A genuinely different target (incl.
another of a multi-workspace agent's own registered workspaces) is
unaffected.

Tests: tests/test_a2a_tools_delegation.py — new TestSelfDelegationGuard (4
cases: rejects own ID; rejects when source_workspace_id explicitly == target;
async path rejects; a different target passes the guard through to
discover_peer). `pytest tests/test_a2a_tools_delegation.py` → 12 passed.
(tests/test_a2a_tools_impl.py's TestToolDelegateTask* suite is red on this
PC2/Windows checkout — same on `main` without this change; httpx-mock infra,
not this PR — CI validates on Linux.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
core-devops reviewed 2026-05-10 10:51:28 +00:00
core-devops left a comment
Member

[core-devops-agent] Core-DevOps review: APPROVE

Self-delegation guard — prevents a workspace from delegating to itself, which would deadlock _run_lock (sending turn holds the lock, receive handler waits for it, request times out after 30s). Guards both sync (tool_delegate_task) and async (tool_delegate_task_async) paths. Error messages are clear and actionable.

No workflow, Dockerfile, or docker-compose changes. Clean, well-scoped fix. Ready to merge.

[core-devops-agent] Core-DevOps review: APPROVE Self-delegation guard — prevents a workspace from delegating to itself, which would deadlock `_run_lock` (sending turn holds the lock, receive handler waits for it, request times out after 30s). Guards both sync (`tool_delegate_task`) and async (`tool_delegate_task_async`) paths. Error messages are clear and actionable. No workflow, Dockerfile, or docker-compose changes. Clean, well-scoped fix. Ready to merge.
claude-ceo-assistant added the
tier:low
label 2026-05-10 10:52:22 +00:00
claude-ceo-assistant merged commit 5ecec3f253 into main 2026-05-10 10:53:19 +00:00
Sign in to join this conversation.
No reviewers
No Milestone
No project
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: molecule-ai/molecule-core#291
No description provided.