Refactor mailbox protocol and add status tracking
Move the protocol documentation to references/ and expand it with read receipts and thread IDs. Update SKILL.md to reference the new location and add a YAML frontmatter block. Remove the outdated MAILBOX.md file.
This commit is contained in:
@@ -1,116 +0,0 @@
|
||||
# Mailbox Protocol
|
||||
|
||||
The mailbox is the file-based communication system for the monkey swarm. It enables agents to send messages to each other and the orchestrator without shared memory or a live connection.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
mail/
|
||||
dir/ ← agent directory (registry of active agents)
|
||||
<agent-id>/
|
||||
inbox/ ← messages received by this agent
|
||||
drafts/ ← messages composed by this agent (staging area)
|
||||
```
|
||||
|
||||
Each agent has its own mailbox under `mail/<agent-id>/`. The orchestrator typically uses `orchestrator` as its ID.
|
||||
|
||||
## Agent Directory (`mail/dir/`)
|
||||
|
||||
`mail/dir/` is the registry of active swarm agents. Every agent writes its own entry when it starts, so other agents (and the orchestrator) can discover who is running and how to reach them.
|
||||
|
||||
### Registering
|
||||
|
||||
When an agent starts, it writes a file to `mail/dir/`:
|
||||
|
||||
```
|
||||
cat > mail/dir/<agent-id>.txt << 'EOF'
|
||||
id: <agent-id>
|
||||
role: <short role name>
|
||||
archetype: <specialist|surveyor|researcher|planner|interfacer>
|
||||
task: <one-line description>
|
||||
EOF
|
||||
```
|
||||
|
||||
Example — `mail/dir/monkey-a3f7.txt`:
|
||||
|
||||
```
|
||||
id: monkey-a3f7
|
||||
role: API integration specialist
|
||||
archetype: specialist
|
||||
task: Implement OAuth2 flow in auth module
|
||||
```
|
||||
|
||||
### Discovering Agents
|
||||
|
||||
Agents can scan `mail/dir/` to find who else is in the swarm:
|
||||
|
||||
```bash
|
||||
ls mail/dir/
|
||||
cat mail/dir/monkey-a3f7.txt
|
||||
```
|
||||
|
||||
Use this to find the right recipient when you need to send mail but don't know which agent ID handles a given role.
|
||||
|
||||
### Cleanup
|
||||
|
||||
When an agent finishes its work, it removes its own entry:
|
||||
|
||||
```
|
||||
rm mail/dir/<agent-id>.txt
|
||||
```
|
||||
|
||||
The orchestrator can also clean up stale entries when a swarm run is complete.
|
||||
|
||||
## Sending Mail
|
||||
|
||||
To send a message to another agent:
|
||||
|
||||
1. **Write a draft** — create the message in your drafts folder:
|
||||
|
||||
```
|
||||
mail/<your-id>/drafts/01_subject-line.txt
|
||||
```
|
||||
|
||||
The prefix number (`01_`) gives ordering; use sequential numbers for related messages.
|
||||
|
||||
2. **Move it to the target's inbox** — atomically deliver by renaming:
|
||||
|
||||
```
|
||||
mv mail/<your-id>/drafts/01_subject-line.txt \
|
||||
mail/<target-id>/inbox/01_subject-line_<hash>.txt
|
||||
```
|
||||
|
||||
The trailing `<hash>` is a short random suffix (e.g. `a3f7`) to avoid filename collisions.
|
||||
|
||||
3. **Use `mv` not copy** — a message is either in your drafts or in the target's inbox, never both. This avoids duplicate reads.
|
||||
|
||||
## Receiving Mail
|
||||
|
||||
- **Check inbox at startup** — read all files in `mail/<your-id>/inbox/` when you begin.
|
||||
- **Check inbox between work units** — scan for new files after completing a logical step.
|
||||
- **Process all pending mail** — read every file in the inbox in filename order.
|
||||
- **Archive after reading** — move processed mail to `mail/<your-id>/sent/` or leave it; the orchestrator can clean up.
|
||||
|
||||
## Mail Format
|
||||
|
||||
Each `.txt` file is a single message with a simple format:
|
||||
|
||||
```
|
||||
To: <recipient-id>
|
||||
From: <sender-id>
|
||||
Subject: <brief description>
|
||||
---
|
||||
<message body>
|
||||
```
|
||||
|
||||
The `---` separator distinguishes headers from the body. The body can be any plain text, code, file paths, or structured data.
|
||||
|
||||
## Rules
|
||||
|
||||
- **Register before you work.** Write your entry to `mail/dir/` as one of your first actions so others can find you.
|
||||
- **Unregister when done.** Remove your `mail/dir/` entry before you exit so stale agents don't linger.
|
||||
- **Your inbox is your signal channel.** The orchestrator uses it to redirect you, cancel work, or provide new context mid-run.
|
||||
- **Keep messages short.** If you have a lot to say, write a file and send a pointer in the mail.
|
||||
- **Always move, never copy.** A message in your drafts is a work-in-progress. Once moved, it's delivered.
|
||||
- **Don't read other agents' inboxes.** Only read your own. If you need to share data with another agent, send it to them — don't peek at their conversations.
|
||||
- **Check before and between.** The inbox is how you learn you've been redirected. Missing mail = missing orders.
|
||||
+30
-17
@@ -1,3 +1,12 @@
|
||||
---
|
||||
name: monkey-swarm
|
||||
description: >
|
||||
Delegates work to specialized sub-agents (monkeys) using behavioral archetypes
|
||||
(specialist, surveyor, researcher, planner, interfacer). Use when the user
|
||||
mentions monkeys, swarm, delegation, or requests that benefit from parallel
|
||||
or specialized agent work. Don't use for simple single-step tasks.
|
||||
---
|
||||
|
||||
# Monkey Swarm
|
||||
|
||||
When the user mentions needing help from the team, monkeys, or swarm — or asks you to delegate work — invoke the monkey swarm. The swarm keeps your context clean by offloading work to specialized sub-agents.
|
||||
@@ -25,34 +34,26 @@ The swarm does **not** spawn agents with fixed roles. Instead, it spawns agents
|
||||
| **planner** | Looks at the current state of the project and proposes next steps. Use when you need a high-level plan, decomposition of work, or prioritization. |
|
||||
| **interfacer** | Comes up with a set of questions for the user. Use when the problem is underspecified and you need more input before proceeding. |
|
||||
|
||||
### Agent Identity and Mailbox
|
||||
|
||||
When spawning a monkey agent:
|
||||
|
||||
1. **Generate an agent ID** — a short random hex string like `monkey-a3f7`. Pass it to the agent in its prompt.
|
||||
2. **Create the mailbox structure** — ensure `mail/<agent-id>/inbox/` and `mail/<agent-id>/drafts/` exist before the agent starts.
|
||||
3. **Pass the orchestrator's ID** — tell the agent the orchestrator's agent ID (e.g. `orchestrator`) so it can send status updates or questions back.
|
||||
4. **Register in the directory** — the agent writes its role, archetype, and task to `mail/dir/<agent-id>.txt` so other agents can discover it. The orchestrator can scan `mail/dir/` to see who's running.
|
||||
5. **Tell the agent to use the mailbox protocol** — reference the `MAILBOX.md` file below.
|
||||
|
||||
The mailbox is the communication channel between swarm agents and the orchestrator. It lives in `mail/` at the repo root. Agents read their inbox at the start of a run and check for new mail between work units. The `mail/dir/` registry keeps track of active agents and their roles.
|
||||
|
||||
### Spawning a Monkey
|
||||
## Spawning a Monkey
|
||||
|
||||
When spawning a monkey agent:
|
||||
|
||||
1. **Identify the archetype** based on what's needed.
|
||||
2. **Generate a persona** — briefly describe the exact role this agent should play, including its scope, goals, and deliverables. Be specific about what "done" looks like.
|
||||
3. **Generate an agent ID** and create its mailbox directories.
|
||||
4. **Include all context** — the agent does not see your conversation history. Provide file paths, requirements, constraints, any relevant background, and its agent ID.
|
||||
5. **Tell the agent to follow the mailbox protocol** (see `MAILBOX.md`).
|
||||
3. **Generate an agent ID** — a short random hex string like `monkey-a3f7`. Pass it to the agent in its prompt.
|
||||
4. **Set up the mailbox** — read `references/mailbox.md` for the full mailbox protocol. At minimum:
|
||||
- Ensure `mail/<agent-id>/inbox/`, `mail/<agent-id>/inbox/.read/`, and `mail/<agent-id>/drafts/` exist before the agent starts.
|
||||
- Pass the orchestrator's ID (e.g. `orchestrator`) so the agent can send status updates or questions back.
|
||||
- Pass a **thread ID** for this agent's conversation with the orchestrator (e.g. `task-refactor-auth`). All messages between the orchestrator and this agent should use the same thread ID.
|
||||
- Tell the agent to register in `mail/dir/<agent-id>.txt` with `status: active` and to update its status as it works.
|
||||
5. **Include all context** — the agent does not see your conversation history. Provide file paths, requirements, constraints, any relevant background, and its agent ID.
|
||||
6. **Use `spawn_agent`** to launch the sub-agent with the persona as its label and the full prompt as its message.
|
||||
|
||||
### Persona Template
|
||||
|
||||
When generating a persona, fill in:
|
||||
|
||||
```
|
||||
```text
|
||||
You are a [ROLE NAME], a [ARCHETYPE] monkey in the swarm.
|
||||
|
||||
## Your Role
|
||||
@@ -72,6 +73,18 @@ You are a [ROLE NAME], a [ARCHETYPE] monkey in the swarm.
|
||||
[Step-by-step or high-level guidance on how to approach the work.]
|
||||
```
|
||||
|
||||
### Mailbox Protocol
|
||||
|
||||
The mailbox is the communication channel between swarm agents and the orchestrator. It lives in `mail/` at the repo root. Agents read their inbox at the start of a run and check for new mail between work units.
|
||||
|
||||
**Key features:**
|
||||
|
||||
- **Read receipts** (`inbox/.read/`) — agents only poll unread messages, preventing context bloat.
|
||||
- **Thread IDs** — group related messages into conversations; the orchestrator and each agent share a thread ID.
|
||||
- **Agent status** (`status:` in `mail/dir/`) — the orchestrator polls status to know who's working, done, or blocked.
|
||||
|
||||
**Load `references/mailbox.md`** for the full protocol: directory structure, registration, sending/receiving rules, mail format, thread protocol, message status, and cleanup.
|
||||
|
||||
### Practical Rules
|
||||
|
||||
- **Keep your context clean.** Offload work whenever a task can be completed by a sub-agent. The orchestrator's job is coordination, not doing everything.
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
# Mailbox Protocol
|
||||
|
||||
The mailbox is the file-based communication system for the monkey swarm. It enables agents to send messages to each other and the orchestrator without shared memory or a live connection.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```text
|
||||
mail/
|
||||
dir/ ← agent directory (registry of active agents)
|
||||
<agent-id>/
|
||||
inbox/ ← messages received by this agent
|
||||
inbox/.read/← read receipts (marks processed messages)
|
||||
drafts/ ← messages composed by this agent (staging area)
|
||||
sent/ ← sent message copies (archive)
|
||||
```
|
||||
|
||||
Each agent has its own mailbox under `mail/<agent-id>/`. The orchestrator typically uses `orchestrator` as its ID.
|
||||
|
||||
### Read Receipts Directory (`inbox/.read/`)
|
||||
|
||||
The `inbox/.read/` directory tracks which inbox messages have been processed. This prevents context bloat: the orchestrator can tell an agent "only read messages without a receipt," and agents can safely archive read mail without losing delivery confirmation.
|
||||
|
||||
## Agent Directory (`mail/dir/`)
|
||||
|
||||
`mail/dir/` is the registry of active swarm agents. Every agent writes its own entry when it starts, so other agents (and the orchestrator) can discover who is running and how to reach them.
|
||||
|
||||
### Registering
|
||||
|
||||
When an agent starts, it writes a file to `mail/dir/`:
|
||||
|
||||
```bash
|
||||
cat > mail/dir/<agent-id>.txt << 'EOF'
|
||||
id: <agent-id>
|
||||
role: <short role name>
|
||||
archetype: <specialist|surveyor|researcher|planner|interfacer>
|
||||
task: <one-line description>
|
||||
status: active
|
||||
EOF
|
||||
```
|
||||
|
||||
Example — `mail/dir/monkey-a3f7.txt`:
|
||||
|
||||
```text
|
||||
id: monkey-a3f7
|
||||
role: API integration specialist
|
||||
archetype: specialist
|
||||
task: Implement OAuth2 flow in auth module
|
||||
status: active
|
||||
```
|
||||
|
||||
### Status Values
|
||||
|
||||
The `status:` field tracks an agent's current state. The orchestrator uses it to know who's working, who's done, and who needs attention.
|
||||
|
||||
| Status | Meaning |
|
||||
| -------- | ---------------------------------------------------------------------- |
|
||||
| `active` | The agent is currently working on its task. |
|
||||
| `paused` | The agent is idle (waiting for input, blocked, or between work units). |
|
||||
| `done` | The agent has completed its task and is ready to exit. |
|
||||
| `error` | The agent encountered a problem it can't resolve on its own. |
|
||||
| `cancel` | The agent's task has been cancelled by the orchestrator. |
|
||||
|
||||
**Status transitions:**
|
||||
|
||||
- Agents update their own status by rewriting `mail/dir/<agent-id>.txt`.
|
||||
- Set `status: done` when you're finished so the orchestrator can clean up.
|
||||
- Set `status: paused` if you're waiting for a response — don't loop on an empty inbox.
|
||||
- Set `status: error` with details in the file body when you need human or orchestrator help.
|
||||
|
||||
### Discovering Agents
|
||||
|
||||
Agents can scan `mail/dir/` to find who else is in the swarm:
|
||||
|
||||
```bash
|
||||
# List active agents
|
||||
ls mail/dir/
|
||||
|
||||
# Read agent details
|
||||
cat mail/dir/monkey-a3f7.txt
|
||||
```
|
||||
|
||||
Use this to find the right recipient when you need to send mail but don't know which agent ID handles a given role.
|
||||
|
||||
### Cleanup
|
||||
|
||||
When an agent finishes its work, it removes its own entry:
|
||||
|
||||
```bash
|
||||
rm mail/dir/<agent-id>.txt
|
||||
```
|
||||
|
||||
The orchestrator can also clean up stale entries when a swarm run is complete.
|
||||
|
||||
## Sending Mail
|
||||
|
||||
To send a message to another agent:
|
||||
|
||||
1. **Write a draft** — create the message in your drafts folder:
|
||||
|
||||
```text
|
||||
mail/<your-id>/drafts/01_subject-line.txt
|
||||
```
|
||||
|
||||
The prefix number (`01_`) gives ordering; use sequential numbers for related messages.
|
||||
|
||||
2. **Move it to the target's inbox** — atomically deliver by renaming:
|
||||
|
||||
```bash
|
||||
mv mail/<your-id>/drafts/01_subject-line.txt \
|
||||
mail/<target-id>/inbox/01_subject-line_<hash>.txt
|
||||
```
|
||||
|
||||
The trailing `<hash>` is a short random suffix (e.g. `a3f7`) to avoid filename collisions.
|
||||
|
||||
3. **Keep a copy** — copy the message to your `sent/` folder for record-keeping:
|
||||
|
||||
```bash
|
||||
cp mail/<target-id>/inbox/01_subject-line_<hash>.txt \
|
||||
mail/<your-id>/sent/01_subject-line_<hash>.txt
|
||||
```
|
||||
|
||||
4. **Use `mv` for delivery, `cp` for copy** — the inbox copy is the delivered message. Your sent copy is for your records.
|
||||
|
||||
## Receiving Mail
|
||||
|
||||
- **Check inbox at startup** — read all files in `mail/<your-id>/inbox/` that have no read receipt.
|
||||
- **Check inbox between work units** — scan for new files after completing a logical step.
|
||||
- **Process all pending mail** — read every file in the inbox in filename order.
|
||||
- **Write a read receipt** — for each message you process, create a receipt:
|
||||
|
||||
```bash
|
||||
touch mail/<your-id>/inbox/.read/<inbox-filename>
|
||||
```
|
||||
|
||||
The receipt is a marker file (can be empty) with the same name as the inbox file. Its presence signals that the message was read and processed.
|
||||
|
||||
- **Unread-only polling** — on subsequent inbox checks, skip files that have a receipt in `inbox/.read/`. This prevents re-reading old messages into your context window.
|
||||
- **Archive after reading** — move processed mail to `mail/<your-id>/sent/` for record-keeping, or delete it to save context tokens. The read receipt remains as proof of delivery.
|
||||
|
||||
### Unread Inbox Query
|
||||
|
||||
To find unread messages:
|
||||
|
||||
```bash
|
||||
# List messages that have no receipt
|
||||
for msg in mail/<your-id>/inbox/*.txt; do
|
||||
[ -f "mail/<your-id>/inbox/.read/$(basename "$msg")" ] || echo "$msg"
|
||||
done
|
||||
```
|
||||
|
||||
## Mail Format
|
||||
|
||||
Each `.txt` file is a single message with a simple format:
|
||||
|
||||
```text
|
||||
To: <recipient-id>
|
||||
From: <sender-id>
|
||||
Subject: <brief description>
|
||||
Thread: <thread-id>
|
||||
Status: <status>
|
||||
---
|
||||
<message body>
|
||||
```
|
||||
|
||||
### Header Fields
|
||||
|
||||
| Header | Required | Description |
|
||||
| --------- | -------- | ------------------------------------------------------------------- |
|
||||
| `To` | Yes | Recipient agent ID. |
|
||||
| `From` | Yes | Sender agent ID. |
|
||||
| `Subject` | Yes | Brief description of the message content. |
|
||||
| `Thread` | No | Groups related messages. See [Thread Protocol](#thread-protocol). |
|
||||
| `Status` | No | Message status for tracking. See [Message Status](#message-status). |
|
||||
|
||||
The `---` separator distinguishes headers from the body. The body can be any plain text, code, file paths, or structured data.
|
||||
|
||||
### Thread Protocol
|
||||
|
||||
The `Thread:` header groups related messages into a conversation. Use a thread ID whenever you're responding to, continuing, or referencing a prior exchange.
|
||||
|
||||
**Thread ID conventions:**
|
||||
|
||||
- Format: a short, human-readable prefix + ID, e.g. `bd-123`, `task-refactor-auth`, `review-4f2a`
|
||||
- The sender of the first message in a thread chooses the thread ID
|
||||
- Replies use the same thread ID; new conversations get new thread IDs
|
||||
- Omit `Thread:` for standalone messages that won't have replies (e.g., fire-and-forget status updates)
|
||||
|
||||
**Thread-based inbox management:**
|
||||
|
||||
- To read a thread, read all messages sharing the same `Thread:` value
|
||||
- To check for replies to your message, grep your inbox for the thread ID:
|
||||
|
||||
```bash
|
||||
grep -l "Thread: bd-123" mail/<your-id>/inbox/*.txt
|
||||
```
|
||||
|
||||
### Message Status
|
||||
|
||||
The `Status:` header on a message tracks its position in the delivery lifecycle. Unlike the agent `status:` field in `mail/dir/`, this is per-message.
|
||||
|
||||
| Status | When to use |
|
||||
| ----------- | -------------------------------------------------------------------- |
|
||||
| (omitted) | Default. New messages sent to an inbox have no status yet. |
|
||||
| `sent` | Sender has delivered the message. |
|
||||
| `delivered` | Recipient has received the message (set after reading). |
|
||||
| `read` | Recipient has read and processed the message (set before archiving). |
|
||||
| `ack` | Recipient acknowledges the message with an explicit reply. |
|
||||
| `done` | The message's purpose is fulfilled; no further action needed. |
|
||||
| `cancelled` | The orchestrator or sender cancelled the message's intent. |
|
||||
| `error` | Processing failed; details in the message body. |
|
||||
|
||||
**Status update flow:**
|
||||
|
||||
- Sender writes the message with no `Status:` (or `Status: sent`)
|
||||
- Recipient reads the message, writes a read receipt, then optionally updates the status:
|
||||
- If the message requires a reply: send a reply with `Status: ack` in the same thread
|
||||
- If the message is informational only: archive it, status becomes implicit `read`
|
||||
- If the message's task is complete: update the message or send `Status: done` in the reply
|
||||
|
||||
**Status and read receipts work together:** The read receipt proves the message was seen. The `Status:` header communicates the semantic outcome. Use both for critical messages; use read receipts alone for fire-and-forget delivery confirmation.
|
||||
|
||||
## Rules
|
||||
|
||||
- **Register before you work.** Write your entry to `mail/dir/` as one of your first actions so others can find you.
|
||||
- **Unregister when done.** Remove your `mail/dir/` entry before you exit so stale agents don't linger.
|
||||
- **Update your status.** Set `status: done` in your directory entry when you finish. The orchestrator polls `mail/dir/` to know who's still working.
|
||||
- **Your inbox is your signal channel.** The orchestrator uses it to redirect you, cancel work, or provide new context mid-run.
|
||||
- **Keep messages short.** If you have a lot to say, write a file and send a pointer in the mail.
|
||||
- **Always move, never copy.** A message in your drafts is a work-in-progress. Once moved, it's delivered.
|
||||
- **Don't read other agents' inboxes.** Only read your own. If you need to share data with another agent, send it to them — don't peek at their conversations.
|
||||
- **Use read receipts for context management.** Only poll unread messages. This prevents re-reading old mail into your context window on every check.
|
||||
- **Use threads for conversations.** Group related messages so you can read a thread as a unit and skip unrelated noise.
|
||||
- **Check before and between.** The inbox is how you learn you've been redirected. Missing mail = missing orders.
|
||||
Reference in New Issue
Block a user