Skip to content

feat: add first-class system handle semantics#682

Open
noodleonthecape wants to merge 2 commits intomainfrom
feat/system-handle
Open

feat: add first-class system handle semantics#682
noodleonthecape wants to merge 2 commits intomainfrom
feat/system-handle

Conversation

@noodleonthecape
Copy link
Copy Markdown
Contributor

@noodleonthecape noodleonthecape commented Apr 1, 2026

Summary

  • add first-class system-handle semantics across the Relay SDK and broker types
  • model agent, human, and system participants separately instead of treating system as a special human
  • update protocol/message mapping and tests to preserve sender kind semantics across the stack

Notes

This removes the old conflation where system() was effectively a human handle. System-origin messages remain ergonomic to send, but are now modeled as a distinct participant kind.


Open with Devin

Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Devin Review found 2 potential issues.

View 5 additional findings in Devin Review.

Open in Devin Review

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 is_human_sender falls through to heuristic for SenderKind::System, allowing potential ACL bypass

The is_human_sender function in src/control.rs only explicitly handles SenderKind::Human (return true) and SenderKind::Agent (return false). The new SenderKind::System variant falls through to the string-based heuristic, which checks whether the sender name starts with "human:". If a system-kind sender happens to have a name matching the human heuristic (e.g. "human:scheduler"), is_human_sender would incorrectly return true. This matters because can_release_child at src/control.rs:16 grants release privileges to human senders — so a misclassified system sender could bypass the owner-check ACL.

(Refers to lines 8-13)

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


event_id: str
from_name: str
from_kind: Optional[SenderKind]
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 Python Message.from_kind is a required field without a default, breaking the public API

In packages/sdk-py/src/agent_relay/relay.py, the Message dataclass has from_kind: Optional[SenderKind] inserted between from_name and to without a default value of None. Despite being Optional, Python dataclasses require fields without defaults to be provided by all callers. Since Message is exported in __all__ (packages/sdk-py/src/agent_relay/__init__.py:82), any external code constructing a Message without specifying from_kind will get a TypeError. Adding = None would maintain backward compatibility.

Suggested change
from_kind: Optional[SenderKind]
from_kind: Optional[SenderKind] = None
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant