From a1682082f6f87126b53efc4892dcd88669f6ef11 Mon Sep 17 00:00:00 2001 From: technical-writer Date: Tue, 2 Jun 2026 06:30:24 -0700 Subject: [PATCH] docs(external-agents): fix Communication Rules to match real CanCommunicate code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Confirmed against workspace-server/internal/registry/access.go (func CanCommunicate): - root-level workspaces (both parent_id NULL) are DENIED, not allowed — the sibling rule requires both to share a non-null parent_id (#1961 removed the root bypass). Doc table said 'Root-level siblings → Yes' (stale); corrected to No. - added ancestor↔descendant (any depth) rows — code allows the full chain, not just direct parent/child. - documented POST /registry/check-access ({caller_id,target_id} → {allowed}) which exposes the same rule programmatically (discovery.go CheckAccess). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../guides/external-agent-registration.md | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/content/docs/guides/external-agent-registration.md b/content/docs/guides/external-agent-registration.md index 81f5686..aad1099 100644 --- a/content/docs/guides/external-agent-registration.md +++ b/content/docs/guides/external-agent-registration.md @@ -277,15 +277,38 @@ The platform enforces strict hierarchy-based access control via | Relationship | Allowed | |---|---| | Same workspace (self-call) | Yes | -| Siblings (same `parent_id`) | Yes | -| Root-level siblings (both `parent_id` is NULL) | Yes | +| Siblings (same non-null `parent_id`) | Yes | +| Root-level workspaces (both `parent_id` is NULL) | **No** | | Parent to child | Yes | | Child to parent | Yes | +| Ancestor to descendant (any depth) | Yes | +| Descendant to ancestor (any depth) | Yes | | Everything else | **Denied** | +The sibling rule requires **both** workspaces to share a non-null `parent_id`, so two +root-level workspaces (each with `parent_id = NULL`) **cannot** communicate — the +root-level bypass was removed (`molecule-core` #1961). Communication also extends up and +down the full ancestor chain, not just direct parent/child. + Canvas requests (no `X-Workspace-ID` header) and system callers (`webhook:*`, `system:*`, `test:*` prefixes) bypass this check. +### Checking access programmatically + +To test whether one workspace may message another without sending a real A2A call, +`POST /registry/check-access`: + +```json +POST /registry/check-access +{ "caller_id": "", "target_id": "" } + +→ 200 OK +{ "allowed": true } +``` + +It evaluates the same `CanCommunicate` rule above and returns `{ "allowed": }` — +useful for previewing the topology before wiring up delegation. + --- ## Canvas Appearance -- 2.52.0