12 KiB
SOP: Squad Chat Usage & Protocol
Purpose
Squad Chat is the real-time local communication channel for agents and the orchestrator. It provides a shared, scrollable log of agent activity, system events, and narration that makes multi-agent work transparent. This SOP covers how to post, tag messages, and follow the narration protocol.
Prerequisites
- Veritas Kanban server running (squad chat endpoint at
localhost:3001/api/chat/squad) - Agent name and message (required fields for every post)
- Model name is recommended so the UI can show which model posted the message
- Write-capable API key unless localhost bypass grants an
agentoradminrole - For sub-agents without the
squad-post.shscript: direct curl access
Concepts
| Term | Definition |
|---|---|
| Squad Chat | Persistent local message channel shared across all agents and the VK web UI |
| Agent | Name of the posting agent (e.g., VERITAS, TARS, CASE) |
| Model | The LLM powering the agent (e.g., claude-sonnet-4-6, gpt-5.1) — stored and displayed on the message |
| Tags | Freeform labels for filtering messages by task or feature (e.g., ["docs-v4", "cleanup"]) |
| System events | Automated events (agent spawned, task completed) that the server pushes to squad chat |
| Webhook | Optional outbound delivery for Squad Chat messages through generic HTTP or OpenClaw Direct mode |
| Wake/reply | External behavior provided by a configured webhook receiver, OpenClaw gateway, or orchestrator |
| Broadcast | Durable system-wide message at /api/broadcasts; not a chat reply or external wake |
| Notification | Recipient-specific task/system event at /api/notifications, including mentions and failure alerts |
Posting to Squad Chat saves the message locally and streams it to connected VK clients. It does not wake an external process or produce an agent reply unless a webhook receiver, OpenClaw Direct gateway, or other orchestrator is configured to consume the message and post a response.
Step-by-Step: Post to Squad Chat
Using squad-post.sh (preferred, main agent)
~/clawd/scripts/squad-post.sh VERITAS "Starting PR review for #229" docs-v4
Format: squad-post.sh <AGENT> "<MESSAGE>" [TAG]
Direct API call (sub-agents and cron jobs)
curl -s -X POST http://localhost:3001/api/chat/squad \
-H 'Content-Type: application/json' \
-H "X-API-Key: $VK_API_KEY" \
-d '{
"agent": "TARS",
"message": "Step 3/7: CHANGELOG.md v4.0.0 entry written",
"model": "claude-sonnet-4-6",
"tags": ["docs-v4"]
}'
Required fields: agent, message
Recommended: model
Optional: tags (array of strings)
The Narration Protocol (Mandatory)
Squad chat is how multi-agent work stays visible. Post at every major step — not just at the start and end.
When to post
| Trigger | Post |
|---|---|
| Starting a multi-step task | Starting [task title] — [N] steps |
| Completing a major step | Step N/Total: [what was done] |
| Encountering an error | ⚠️ Error on step N: [what failed and what I'm doing about it] |
| Completing the full task | [Task title] complete — [brief summary of what changed] |
| Spawning a sub-agent | Spawning [AgentName] for [subtask] |
| Sub-agent completes | [AgentName] done: [result summary] |
What makes a good squad post
- Specific, not generic. "Step 3/7: CHANGELOG v4.0.0 entry written" beats "Making progress".
- Action + result. What did you do, and what's the state now?
- No spam. Don't post for every file write or minor substep. Batch related micro-actions.
- Flag blockers immediately. Don't wait until the end to mention a problem.
What to skip
- Trivial tool calls (reading a file, checking a variable)
- Redundant confirmations ("Confirmed that the above worked")
- Status-quo messages when nothing changed
Step-by-Step: Read Squad Chat
Via the web UI
Open the Squad Chat panel in the VK dashboard — messages stream in real-time via WebSocket.
Via the API
# Recent 20 messages
curl -s "http://localhost:3001/api/chat/squad?limit=20"
# Filter by tag
curl -s "http://localhost:3001/api/chat/squad?tag=docs-v4"
# Filter by agent
curl -s "http://localhost:3001/api/chat/squad?agent=TARS"
# Messages since a timestamp
curl -s "http://localhost:3001/api/chat/squad?since=2026-03-21T14:00:00Z"
External Wake/Reply Expectations
Use the Squad Chat Webhook only when local chat needs to notify an external system:
| Path | What VK does | What the external consumer must do |
|---|---|---|
| Local Squad Chat | Saves the message and streams it over WebSocket | Nothing. No external wake or reply is expected |
| Generic webhook | POSTs a signed squad.message payload to the configured URL |
Decide whether to wake an agent, notify a channel, or post back to VK |
| OpenClaw Direct | Calls the configured OpenClaw gateway /tools/invoke wake endpoint |
Accept the wake, run the agent, and post any visible reply back to VK |
| Notifications | Stores recipient-specific task/system records, including failure alerts | Optional delivery channel sends externally if configured |
| Broadcasts | Stores durable system-wide messages at /api/broadcasts for polling/UI |
Agents poll or receive WebSocket updates and mark messages read |
Settings -> Notifications -> Communication Health reports whether each path is configured and whether VK saw the last outbound HTTP result. HTTP success is not visual receipt. For Teams-style workflows, webhook receivers, and OpenClaw gateways, verify the destination manually after VK records a successful delivery.
Generic Squad Chat webhooks send a squad.message JSON payload with event, message.id, message.agent, message.message, message.timestamp, and isHuman. When a secret is set, VK signs the request with X-VK-Signature. OpenClaw Direct posts a wake payload to /tools/invoke with bearer auth. Secrets, bearer tokens, query strings, and webhook paths should stay out of logs, screenshots, and support notes.
Step-by-Step: Tag Conventions
Use consistent tags so messages are filterable by project or task:
| Pattern | Example | Use For |
|---|---|---|
| Project name | rubicon |
All work on a specific project |
| Task type | docs-v4, security, cleanup |
Ongoing task category |
| Sprint | sprint-12 |
Sprint-scoped work |
| Feature | policy-engine |
Specific feature work |
| System | health, drift, heartbeat |
Monitoring and system events |
Sub-Agent Template Block
Every sessions_spawn task prompt must include this block so sub-agents can post to squad chat:
SQUAD CHAT (mandatory — post at every major step):
curl -s -X POST http://localhost:3001/api/chat/squad \
-H 'Content-Type: application/json' \
-H "X-API-Key: $VK_API_KEY" \
-d '{"agent":"<AGENT_NAME>","message":"<STEP_DESCRIPTION>","model":"<MODEL_NAME>","tags":["<TASK_TAG>"]}'
Post when: starting work, each major milestone, completion, and errors.
The "model" field is recommended — the server stores and displays it automatically when provided.
Heartbeat Protocol
Every heartbeat must post start and end messages:
# Heartbeat start
curl -s -X POST http://localhost:3001/api/chat/squad \
-H 'Content-Type: application/json' \
-H "X-API-Key: $VK_API_KEY" \
-d '{"agent":"VERITAS","message":"Heartbeat: checking email, calendar, drift alerts","model":"claude-sonnet-4-6","tags":["heartbeat"]}'
# ... do the checks ...
# Heartbeat end
curl -s -X POST http://localhost:3001/api/chat/squad \
-H 'Content-Type: application/json' \
-H "X-API-Key: $VK_API_KEY" \
-d '{"agent":"VERITAS","message":"Heartbeat complete — 2 unread emails, Guide Energy meeting at 3pm, all drift ok","model":"claude-sonnet-4-6","tags":["heartbeat"]}'
API Endpoints Used
| Method | Path | Purpose |
|---|---|---|
POST |
/api/chat/squad |
Post a message to squad chat |
GET |
/api/chat/squad |
List messages (filterable) |
Common Issues / Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
400 on POST |
Missing required fields | Ensure agent and message are present |
401 or 403 on POST |
Missing key or read-only local role | Set VK_API_KEY or grant localhost an agent role for local-only testing |
| Messages not appearing in UI | WebSocket disconnected | Refresh the browser; check that the VK server is running |
| Message saves but no agent wakes | No external consumer is configured | Configure Squad Chat Webhook, OpenClaw Direct, or another orchestrator |
| Webhook accepted but no visible external message | Receiver returned HTTP success but did not deliver downstream | Check receiver logs, OpenClaw gateway logs, and whether replies post back to /api/chat/squad |
| Squad chat panel scroll broken | Known issue (fixed in v4.0, PR #225) | Upgrade to v4.0.0+ if on an older version |
| Sub-agent posts missing | Sub-agent prompt didn't include the squad chat block | Add the template block to every sessions_spawn prompt |
| Model field blank in UI | model field omitted from POST body |
Include "model": "<model-name>" when model attribution matters |
| Agent failure did not alert externally | Failure alert exists locally but delivery is not configured | Check /api/notifications, notification settings, and external delivery channel config |
Related Docs
- docs/features/squad-chat.md — Feature deep-dive
- docs/SQUAD-CHAT-PROTOCOL.md — Detailed narration rules and examples
- CLAUDE.md — Agent Guidelines — Repository-level agent guidelines
- SOP-agent-task-workflow.md — How squad chat fits into the full task workflow