Skip to content

Hybrid relay-broker integration: best of #412 + #404#415

Merged
khaliqgant merged 10 commits intomainfrom
feature/relay-broker-hybrid
Feb 13, 2026
Merged

Hybrid relay-broker integration: best of #412 + #404#415
khaliqgant merged 10 commits intomainfrom
feature/relay-broker-hybrid

Conversation

@khaliqgant
Copy link
Copy Markdown
Member

@khaliqgant khaliqgant commented Feb 13, 2026

Summary

Integrates the Rust relay-broker into the main repo using a hybrid approach that combines the best code quality from PR #412 with the backward compatibility of PR #404.

Bug fixes from PR #412:

  1. Security: sender identity spoofing — agents could name themselves human:... to bypass release ACL checks
  2. URL double-path — Relaycast WS URLs with /stream base produced invalid host/stream/v1/stream
  3. Function name typoensure_reaycast_mcp_configensure_relaycast_mcp_config
  4. Unbounded message coalescing — added 32 KiB MAX_COALESCED_BODY_SIZE cap
  5. Code duplication — exported terminate_child as pub instead of duplicating inline

Compatibility shims:

  • @agent-relay/utils/relay-pty-path re-exported as alias for agent-relay-path
  • RelayPtyOrchestrator re-exported as alias for RelayBrokerOrchestrator
  • AGENT_RELAY_BINARY env var with legacy RELAY_PTY_BINARY fallback

Security:

  • ACTION REQUIRED: Rotate leaked key rk_live_b00fd0ddeca96468d72140c9c4b3a910 (was committed in PR start broker integration #404, removed in this PR but still in git history)

Validation Matrix

Repo Check Status
relay Rust broker tests (139) ✅ PASS
relay Utils shim tests (37) ✅ PASS
relay-cloud npm build ✅ PASS
relay-cloud TypeScript compile ✅ PASS
relay-cloud Runtime import checks ✅ PASS
relay-dashboard Server build ✅ PASS
relay-dashboard Runtime alias imports ✅ PASS
relay-dashboard Full UI build (Next prerender) ⚠️ Pre-existing issue, unrelated

Context: Why hybrid?

Collaborators

This PR was produced by a multi-agent team coordinated via Agent Relay:

Agent Role Model Harness
Broker-1 PR analysis, Rust fix backports, secret remediation, test validation Claude Opus 4.6 Agent Relay (claude)
Broker-2 Cross-repo dependency analysis, compatibility shims, smoke test matrix GPT-5 Codex CLI + Agent Relay
Dashboard Coordination, approval, task direction Agent Relay Dashboard

Decisions and reasoning recorded via trail — see .trajectories/ for full trajectory.

Test plan

  • Rust broker tests pass (139/139)
  • Utils shim tests pass (37/37)
  • relay-cloud builds and compiles
  • relay-dashboard server builds
  • Runtime import alias checks pass
  • Rotate leaked API key
  • Manual end-to-end: spawn agent via broker, send messages, verify dashboard

🤖 Generated with Claude Code

khaliqgant and others added 9 commits February 13, 2026 10:48
Pull relay-broker directory from relay-broker-integration branch as the
foundation for the hybrid approach. Will apply bug fixes from PR #412 on top.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevent agents from spoofing human identity by naming themselves
"human:..." to bypass release ACL checks. When sender_kind is
explicitly Agent, immediately return false regardless of name string.

Cherry-picked from PR #412.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When base URL already ends with /stream (e.g. wss://rt.relaycast.dev/stream),
avoid appending /v1/stream which produced invalid double-path URLs like
wss://host/stream/v1/stream. Now correctly preserves the existing /stream path.

Cherry-picked from PR #412.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename ensure_reaycast_mcp_config to ensure_relaycast_mcp_config
(missing 'l' in relaycast). Updated all call sites in main.rs.

Cherry-picked from PR #412.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Without a body-size bound, a burst of large messages from the same
sender within the coalesce window would concatenate without limit,
potentially causing large memory allocations. Add MAX_COALESCED_BODY_SIZE
(32 KiB) check that flushes the current group when exceeded.

Cherry-picked from PR #412.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Make terminate_child public so it can be reused from main.rs instead
of being duplicated inline, reducing code duplication.

Cherry-picked from PR #412.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace committed rk_live_... key with environment variable placeholder.
The exposed key (rk_live_b00fd0ddeca96468d72140c9c4b3a910) must be
rotated immediately.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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 3 potential issues.

🐛 1 issue in files not directly in the diff

🐛 Panic on multi-byte UTF-8 in listen-mode message truncation (relay-broker/src/main.rs:1168)

In main.rs listen mode, relay message text is truncated using byte-level slicing &mapped.text[..120] which will panic if byte 120 falls in the middle of a multi-byte UTF-8 character.

Root Cause

At relay-broker/src/main.rs:1167-1168, the code checks mapped.text.len() > 120 (byte length) and then slices at byte 120:

if mapped.text.len() > 120 {
    format!("{}…", &mapped.text[..120])  // PANIC if byte 120 is mid-character
}

The mapped.text field contains user-generated relay messages which commonly include emoji (👋, 🚀), CJK characters, or other multi-byte UTF-8 content. When such a message exceeds 120 bytes, the byte-level slice will panic with byte index 120 is not a char boundary.

Note that the codebase already has a floor_char_boundary helper function defined at relay-broker/src/main.rs:2864-2873 that correctly handles this case, but it's not used here.

Impact: Any relay message in listen mode containing multi-byte UTF-8 characters that exceeds 120 bytes will crash the broker.

View 11 additional findings in Devin Review.

Open in Devin Review

Comment thread relay-broker/src/conversation_log.rs Outdated
Comment thread relay-broker/src/relaycast_ws.rs
Fix potential panics when truncating multi-byte UTF-8 strings (emoji,
CJK, accented characters) in conversation_log.rs and main.rs listen mode.

Adds floor_char_boundary helper to conversation_log.rs and applies it
to truncate(), pad_or_truncate(), and short_id(). Also fixes the same
pattern in main.rs listen-mode message display.

Addresses Devin review finding on PR #415.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@khaliqgant khaliqgant merged commit 0a53aec into main Feb 13, 2026
32 checks passed
@khaliqgant khaliqgant deleted the feature/relay-broker-hybrid branch February 13, 2026 10:29
khaliqgant added a commit that referenced this pull request Feb 13, 2026
khaliqgant added a commit that referenced this pull request Feb 13, 2026
Fix potential panics when truncating multi-byte UTF-8 strings (emoji,
CJK, accented characters) in conversation_log.rs and main.rs listen mode.

Adds floor_char_boundary helper to conversation_log.rs and applies it
to truncate(), pad_or_truncate(), and short_id(). Also fixes the same
pattern in main.rs listen-mode message display.

Addresses Devin review finding on PR #415.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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