← Back to blog
May 23, 2026Dzianis Vashchuk6 min read

How AI Agents Talk to Each Other at Vibe Technologies — Slack Apps, OpenClaw Bindings, and the AGENTS.md Handoff Matrix

Every agent at Vibe Technologies has its own Slack app, bound to a dedicated OpenClaw channel. When one Slack bot @mentions another, OpenClaw routes the message to the target agent's session. AGENTS.md in each workspace is the plain-text contract that tells each agent when to pass work and to whom.

Vibe Technologies has one human and ten AI agents. The human rarely coordinates handoffs directly — agents hand off to each other. Jared Dunn (SupportEngineer) escalates to Gilfoyle Bertram (SoftwareEngineer), who hands off to the CTO when the fix requires architecture authority. This post explains the exact mechanism: one Slack app per agent, one OpenClaw channel binding per agent, and a per-workspace AGENTS.md that every agent reads at session start.

Note on the previous architecture: Earlier in the series (VibeTeam: OpenHands AI Operations Agents), agents were wired through a custom FastAPI gateway (vibeteam-gateway) with per-agent agents.yaml definitions. That is the OpenHands-era stack. Everything described in this post is the current OpenClaw stack.

The Problem

When the team ran on the OpenHands gateway, all agent traffic flowed through a single service with a single Slack bot. There was no way to address one agent without the others picking up the event. Handoffs required manual context copy-paste between sessions.

Switching to OpenClaw changed the model: each agent is an independent process with its own channel binding. Slack apps replaced the shared bot. AGENTS.md replaced hardcoded routing tables.

What We Built

Agents Defined in openclaw.json

All agents are declared in openclaw.json under agents.list. Each entry has an ID and an isolated workspace:

{
  "agents": {
    "defaults": {
      "model": {
        "primary": "litellm/gpt-5.3-codex",
        "fallbacks": ["litellm/gpt-5.1", "litellm/gpt-4.1"]
      }
    },
    "list": [
      { "id": "support-engineer",  "workspace": "~/.openclaw/workspace/support-engineer" },
      { "id": "software-engineer", "workspace": "~/.openclaw/workspace/software-engineer" },
      { "id": "product-manager",   "workspace": "~/.openclaw/workspace/product-manager" },
      { "id": "marketing-manager", "workspace": "~/.openclaw/workspace/marketing-manager" },
      { "id": "growth-manager",    "workspace": "~/.openclaw/workspace/growth-manager" },
      { "id": "cto",               "workspace": "~/.openclaw/workspace/cto" },
      { "id": "investor",          "workspace": "~/.openclaw/workspace/investor" },
      { "id": "taxadvisor",        "workspace": "~/.openclaw/workspace/taxadvisor" },
      { "id": "immigration-lawyer","workspace": "~/.openclaw/workspace/immigration-lawyer" },
      { "id": "claw",              "workspace": "~/.openclaw/workspace/claw", "default": true }
    ]
  }
}

Config hot-reloads — no restart needed after adding or removing an agent.

One Slack App Per Agent, Bound via OpenClaw

Each agent gets its own Slack app. That app registers a bot user in Slack — @SupportEngineer, @SoftwareEngineer, etc. — with its own bot token and webhook endpoint.

The binding that connects the Slack app to the OpenClaw agent is a single CLI command:

openclaw agents bind --agent support-engineer  --bind slack:support-channel
openclaw agents bind --agent software-engineer --bind slack:software-channel
openclaw agents bind --agent product-manager   --bind slack:product-channel

Or as a JSON block in openclaw.json:

"bindings": [
  { "agentId": "support-engineer",  "match": { "channel": "slack", "accountId": "support-channel" } },
  { "agentId": "software-engineer", "match": { "channel": "slack", "accountId": "software-channel" } },
  { "agentId": "product-manager",   "match": { "channel": "slack", "accountId": "product-channel" } }
]

When a Slack message arrives on the support-channel account, OpenClaw routes it to Jared Dunn's session. When a message arrives on software-channel, it goes to Gilfoyle Bertram.

@mention Is the Handoff Trigger

When Jared Dunn's response contains @SoftwareEngineer, OpenClaw detects the mention and delivers the message to the software-channel binding — which triggers Gilfoyle Bertram's session with the full thread context:

Customer email → Jared Dunn (support-channel)
  Jared writes: "@SoftwareEngineer — login flow returns 500 for subdomain X.
                 Sentry issue VIBE-4821. Please investigate."
                ↓
OpenClaw detects @SoftwareEngineer mention
                ↓
Routes to software-channel → Gilfoyle Bertram's session
                ↓
Gilfoyle opens PR, links "Fixes VIBE-4821"
                ↓
PR merge event → Jared notified → replies to customer

No custom gateway code. No regex parsing in application code. OpenClaw's multi-agent routing handles it.

AGENTS.md Is the Handoff Contract

Every agent workspace contains an AGENTS.md. At session start, the agent reads this file. It includes a handoff table — the plain-text contract that tells the agent when to pass work and to whom:

## Handoff Guidelines

| Situation | Handoff To | Example |
|-----------|------------|---------|
| Infrastructure outage (5xx errors) | @GilfoyleBertram | "API returning 503. @GilfoyleBertram check service health." |
| Code bug or feature request | @SoftwareEngineer | "Found login bug. @SoftwareEngineer investigate issue #345." |
| Product prioritization | @ProductManager | "Customer asking about roadmap. @ProductManager advise on timeline." |
| Public announcement needed | @MarketingManager | "Outage resolved. @MarketingManager post status update." |

This is not a config file. It is instructions. The agent reads it, applies the rules, writes the @mention into its response, and OpenClaw delivers the message. The routing is data-driven without being over-engineered.

When responsibility shifts — a new agent is added, an existing role expands — the handoff table changes in one file. Every agent picks up the update on next session start.

GitHub Identity Per Agent

Each agent also carries its own GitHub App credentials in its binding config. PRs opened by Gilfoyle Bertram appear under his bot identity. Issues created by Jared Dunn show his bot as the author. Audit trail intact.

Evidence It Works

We haven't measured handoff latency systematically. What we can confirm:

  • Jared Dunn escalates to Gilfoyle Bertram via @mention multiple times per week without human involvement.
  • openclaw agents list --bindings shows all ten agents active with their respective Slack bindings.
  • Each agent's GitHub PRs appear under the correct bot identity — no mixed authorship.

What Does Not Work Yet

  • No handoff acknowledgment. When Jared hands off to Gilfoyle, there is no explicit "received" signal back. Jared doesn't know Gilfoyle acted on the task until a PR appears.
  • No circular handoff guard. OpenClaw prevents self-handoffs but doesn't detect multi-agent loops (A → B → A). Not seen in practice, but the guardrail is absent.
  • No priority queue. A P0 incident and a low-priority feature request hit Gilfoyle's Slack channel in the same order. Jared labels Linear issues by severity, but that label doesn't influence routing speed.
  • Cost not yet reported. Active tuning phase — cost numbers during debugging don't reflect steady-state. Will publish once the system stabilizes.

The full #ainativecompany series:

Questions or running a similar setup: [email protected]

Previous in series: Linear Customer Support Pipeline →

Next in series: Meet the Vibe Technologies Team: 10 AI Agents, One Human, One Framework →

Read next

Related posts