Forked clean from public hackathon repo (Starfire-AgentTeam, BSL 1.1) with full rebrand to Molecule AI under github.com/Molecule-AI/molecule-monorepo. Brand: Starfire → Molecule AI. Slug: starfire / agent-molecule → molecule. Env vars: STARFIRE_* → MOLECULE_*. Go module: github.com/agent-molecule/platform → github.com/Molecule-AI/molecule-monorepo/platform. Python packages: starfire_plugin → molecule_plugin, starfire_agent → molecule_agent. DB: agentmolecule → molecule. History truncated; see public repo for prior commits and contributor attribution. Verified green: go test -race ./... (platform), pytest (workspace-template 1129 + sdk 132), vitest (canvas 352), build (mcp). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
131 lines
4.4 KiB
Markdown
131 lines
4.4 KiB
Markdown
# Communication Rules
|
|
|
|
The hierarchy IS the topology. There is no manual connection wiring — communication is derived automatically from the parent/child structure.
|
|
|
|
## The Rules
|
|
|
|
| Direction | Allowed? | Example |
|
|
|-----------|----------|---------|
|
|
| Sibling <-> sibling | Yes | Marketing <-> Developer PM |
|
|
| Parent -> child (PM delegates down) | Yes | Developer PM -> Frontend Agent |
|
|
| Child -> parent (report up to PM) | Yes | Frontend Agent -> Developer PM |
|
|
| Skip levels (grandchild -> grandparent) | No | Frontend Agent -> Business Core |
|
|
| Cross-team (different parents) | No | Frontend Agent -> Operations |
|
|
|
|
## Visual Example
|
|
|
|
```
|
|
Business Core
|
|
+-- Marketing <--can talk--> Developer PM
|
|
+-- Developer PM <--can talk--> Operations
|
|
| +-- Frontend <--can talk--> Backend
|
|
| +-- Backend <--can talk--> QA PM
|
|
| +-- QA PM
|
|
| +-- Auto Test <--can talk--> Manual Review
|
|
| +-- Manual Review
|
|
+-- Operations
|
|
```
|
|
|
|
- Developer PM can talk to Marketing and Operations (siblings) AND down to Frontend, Backend, QA PM (its children)
|
|
- Frontend can only talk to Backend and QA PM (siblings) and up to Developer PM (its parent)
|
|
- Frontend **cannot** talk to Marketing, Business Core, or Operations
|
|
- Auto Test can only talk to Manual Review (sibling) and up to QA PM (its parent)
|
|
|
|
## Access Check
|
|
|
|
The platform validates every discovery request with a hierarchy check:
|
|
|
|
```go
|
|
func CanCommunicate(callerID, targetID string) bool {
|
|
caller := db.GetWorkspace(callerID)
|
|
target := db.GetWorkspace(targetID)
|
|
|
|
// siblings — same parent (including root-level where both have no parent)
|
|
if caller.ParentID != nil && target.ParentID != nil &&
|
|
*caller.ParentID == *target.ParentID {
|
|
return true
|
|
}
|
|
// root-level siblings — both have no parent
|
|
if caller.ParentID == nil && target.ParentID == nil {
|
|
return true
|
|
}
|
|
|
|
// parent talking to child
|
|
if caller.ID == target.ParentID {
|
|
return true
|
|
}
|
|
|
|
// child talking up to parent
|
|
if target.ID == caller.ParentID {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
```
|
|
|
|
`GET /registry/discover/:id` reads the caller's identity from the `X-Workspace-ID` header, runs `CanCommunicate()`, and returns **403 Forbidden** if the caller isn't allowed.
|
|
|
|
## Peer Discovery
|
|
|
|
Instead of a connections table, the platform derives reachable workspaces from the hierarchy:
|
|
|
|
```
|
|
GET /registry/:id/peers
|
|
```
|
|
|
|
Returns: siblings + children + parent (all workspaces this one can communicate with).
|
|
|
|
```python
|
|
async def get_reachable_workspaces(workspace_id: str) -> list:
|
|
ws = db.GetWorkspace(workspace_id)
|
|
reachable = []
|
|
|
|
# siblings — same parent
|
|
if ws.parent_id:
|
|
siblings = db.GetChildren(ws.parent_id)
|
|
reachable += [s for s in siblings if s.id != workspace_id]
|
|
|
|
# children — own sub-workspaces
|
|
children = db.GetChildren(workspace_id)
|
|
reachable += children
|
|
|
|
# parent — can talk up
|
|
if ws.parent_id:
|
|
parent = db.GetWorkspace(ws.parent_id)
|
|
reachable.append(parent)
|
|
|
|
return reachable
|
|
```
|
|
|
|
## What This Replaces
|
|
|
|
The hierarchy-based model removes several components:
|
|
|
|
| Removed | Replaced by |
|
|
|---------|-------------|
|
|
| `workspace_connections` table | `parent_id` on `workspaces` table |
|
|
| `CONNECTION_CREATED` / `CONNECTION_REMOVED` events | `WORKSPACE_EXPANDED` / `WORKSPACE_COLLAPSED` events |
|
|
| `/topology/connect` endpoint | Nesting via drag-into on canvas |
|
|
| Canvas edge drawing UI | Edges auto-rendered from hierarchy |
|
|
| Workspace whitelist table | `CanCommunicate()` hierarchy check |
|
|
| Bundle connection definitions | Bundle `sub_workspaces` array |
|
|
|
|
## Canvas Behavior
|
|
|
|
- **No edge drawing.** Users don't wire workspaces — they **nest** them
|
|
- Edges render **automatically** from parent/child relationships
|
|
- The visual is a true **org chart**, not a flowchart
|
|
- Dragging a workspace **inside** another workspace nests it as a sub-workspace
|
|
|
|
## Why This Is Better
|
|
|
|
The org chart IS the access control policy. Simpler schema, simpler security, simpler canvas. No configuration drift between "who should talk to whom" and "who can talk to whom."
|
|
|
|
## Related Docs
|
|
|
|
- [Team Expansion](../agent-runtime/team-expansion.md) — How nesting works
|
|
- [System Prompt Structure](../agent-runtime/system-prompt-structure.md) — How peer capabilities are injected
|
|
- [A2A Protocol](./a2a-protocol.md) — Discovery flow
|
|
- [Platform API](./platform-api.md) — Endpoint reference
|