|
Some checks failed
CI / Canvas Deploy Reminder (pull_request) Blocked by required conditions
Block internal-flavored paths / Block forbidden paths (pull_request) Successful in 6s
CI / Detect changes (pull_request) Successful in 9s
publish-runtime-autobump / bump-and-tag (pull_request) Has been skipped
Handlers Postgres Integration / detect-changes (pull_request) Successful in 17s
CI / Shellcheck (E2E scripts) (pull_request) Successful in 26s
E2E Staging Canvas (Playwright) / detect-changes (pull_request) Successful in 25s
E2E API Smoke Test / detect-changes (pull_request) Successful in 26s
E2E Chat / detect-changes (pull_request) Successful in 27s
Runtime PR-Built Compatibility / detect-changes (pull_request) Successful in 23s
Secret scan / Scan diff for credential-shaped strings (pull_request) Successful in 20s
Handlers Postgres Integration / Handlers Postgres Integration (pull_request) Successful in 8s
qa-review / approved (pull_request) Failing after 20s
security-review / approved (pull_request) Failing after 21s
sop-tier-check / tier-check (pull_request) Successful in 18s
sop-checklist / all-items-acked (pull_request) Successful in 20s
publish-runtime-autobump / pr-validate (pull_request) Successful in 51s
gate-check-v3 / gate-check (pull_request) Successful in 33s
E2E Staging Canvas (Playwright) / Canvas tabs E2E (pull_request) Successful in 15s
E2E API Smoke Test / E2E API Smoke Test (pull_request) Successful in 14s
E2E Chat / E2E Chat (pull_request) Successful in 51s
lint-required-no-paths / lint-required-no-paths (pull_request) Successful in 1m34s
Runtime PR-Built Compatibility / PR-built wheel + import smoke (pull_request) Successful in 3m22s
CI / Python Lint & Test (pull_request) Successful in 7m52s
CI / Canvas (Next.js) (pull_request) Successful in 22m40s
CI / Platform (Go) (pull_request) Successful in 23m33s
CI / all-required (pull_request) Successful in 24m11s
A workspace delegating to a target that never picks up the task hits
the 300s polling timeout; tool_delegate_task then reports the outcome
via a2a_tools.report_activity("a2a_receive", ...), which POSTs an
activity_type='a2a_receive' row to /workspaces/<self>/activity with
source_id=WORKSPACE_ID (its own id — mandated by the workspace-server's
source_id spoof-defense, activity.go:549) and method='message/send'.
The workspace's own inbox poller then re-fetches that row from
?type=a2a_receive; message_from_activity sets peer_id=source_id
(non-empty) so to_dict classifies it kind=peer_agent, registry-resolved
to the workspace's own display name ("mac laptop"). The agent sees its
own delegation-failure echoed back as if a peer delegated to it
(confirmed live on hongming.moleculesai.app 2026-05-16).
This is NOT a self-delegation (the platform + agent self-delegation
guards are correct and fire on source==target — the real target here
was a different workspace that legitimately timed out). The producer
side is also correct by platform contract (report_activity MUST send
source_id=WORKSPACE_ID). The defect is the inbox poller mis-classifying
a self-originated bookkeeping row as an inbound peer message — the same
class as the already-fixed self-notify echo, slipping through because
it uses method='message/send' + non-empty self source_id.
Fix at the correct layer (the consumer): add inbox._is_self_echo_row
and skip+advance-cursor for any a2a_receive row whose source_id equals
the polled workspace_id, mirroring _is_self_notify_row exactly. A
genuine inbound peer always has source_id != polled workspace_id
(self-delegation is blocked upstream by two guards). RFC #2829 PR-2
delegation-result pushes (method='delegate_result', source_id==self)
are explicitly preserved so the durable async result-delivery path
keeps working.
Tests: 8 new tests (predicate + integrated _poll_once skip/cursor +
delegate_result preservation). test_inbox.py 62/62 green; related
delegation/a2a suites 48/48 green; zero regression.
Refs: molecule-ai/internal#469
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
||
|---|---|---|
| .. | ||
| adapters | ||
| audit | ||
| builtin_tools | ||
| lib | ||
| molecule_audit | ||
| platform_tools | ||
| plugins_registry | ||
| policies | ||
| scripts | ||
| skill_loader | ||
| tests | ||
| _sanitize_a2a.py | ||
| .coveragerc | ||
| a2a_cli.py | ||
| a2a_client.py | ||
| a2a_executor.py | ||
| a2a_mcp_server.py | ||
| a2a_response.py | ||
| a2a_tools_delegation.py | ||
| a2a_tools_inbox.py | ||
| a2a_tools_memory.py | ||
| a2a_tools_messaging.py | ||
| a2a_tools_rbac.py | ||
| a2a_tools.py | ||
| adapter_base.py | ||
| agent.py | ||
| agents_md.py | ||
| boot_routes.py | ||
| build-all.sh | ||
| card_helpers.py | ||
| config.py | ||
| configs_dir.py | ||
| consolidation.py | ||
| coordinator.py | ||
| Dockerfile | ||
| entrypoint.sh | ||
| event_log.py | ||
| events.py | ||
| executor_helpers.py | ||
| heartbeat.py | ||
| inbox_uploads.py | ||
| inbox.py | ||
| initial_prompt.py | ||
| internal_chat_uploads.py | ||
| internal_file_read.py | ||
| main.py | ||
| mcp_cli.py | ||
| mcp_doctor.py | ||
| mcp_heartbeat.py | ||
| mcp_inbox_pollers.py | ||
| mcp_workspace_resolver.py | ||
| molecule_ai_status.py | ||
| not_configured_handler.py | ||
| platform_auth.py | ||
| platform_inbound_auth.py | ||
| plugins.py | ||
| preflight.py | ||
| prompt.py | ||
| pytest.ini | ||
| rebuild-runtime-images.sh | ||
| requirements.txt | ||
| runtime_wedge.py | ||
| secret_redactor.py | ||
| shared_runtime.py | ||
| smoke_mode.py | ||
| transcript_auth.py | ||
| watcher.py | ||