# Munder Difflin Communication Protocol: How Agents Exchange Messages via the File-Based Hive System

> Discover the Munder Difflin communication protocol. Agents exchange messages using a file-based Hive system, writing to outbox and reading from inbox directories.

- Repository: [Chaitanya Giri/munder-difflin](https://github.com/chaitanyagiri/munder-difflin)
- Tags: internals
- Published: 2026-08-28

---

**Munder Difflin uses a file-based Hive protocol where agents communicate by writing JSON messages to `outbox/` directories and reading from `inbox/` directories, with a central harness handling all routing and Git operations.**

The **Munder Difflin communication protocol** enables coordination between autonomous agents without network sockets or external services. Each agent maintains isolated workspace directories, and the harness mediates all inter-agent messaging through atomic file operations. This design produces deterministic, auditable, and replayable agent interactions persisted entirely on disk.

## How the Hive Protocol Routes Messages Between Agents

In [`src/main/hive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/hive.ts), the protocol defines a rigid directory structure that enforces the single-writer rule. Agents never access another agent's folders directly—they interact only with their own `outbox/` and `inbox/` directories.

The message flow follows three stages:

1. **Outbound** – An agent writes a `.json` file to its `agents/<agent-id>/outbox/` folder.
2. **Routing** – The harness detects the new file, validates it, and copies it to the target agent's `inbox/`.
3. **Inbound** – The receiving agent processes messages from `inbox/` at task start, then archives handled messages to `inbox/.done/`.

This file-based approach eliminates race conditions since the harness serializes all Git operations and file movements. As implemented in `chaitanyagiri/munder-difflin`, the protocol guarantees at-least-once delivery with exactly-once processing semantics.

## JSON Message Schema and Auto-Populated Fields

The **protocol schema** from [`PROTOCOL.md`](https://github.com/chaitanyagiri/munder-difflin/blob/main/PROTOCOL.md) (embedded in [`src/main/hive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/hive.ts) at line 2616) defines the base message structure:

```json
{
  "to": "<agent-id> | god | broadcast",
  "act": "request | inform | propose | query | agree | refuse | done",
  "subject": "one-line summary",
  "body": "the details",
  "conversation": "optional thread identifier",
  "in_reply_to": "optional prior message id"
}

```

When the harness ingests a file, it automatically injects additional metadata:

| Field | Added By | Purpose |
|-------|----------|---------|
| `id` | Harness | Unique message identifier |
| `from` | Harness | Source agent ID |
| `hops` | Harness | Routing hop counter for loop detection |
| `timestamp` | Harness | ISO 8601 arrival time |

This separation of concerns lets agents focus on business logic while the infrastructure handles provenance and audit trails.

## Sending Messages: Agent-Side Implementation

Agents construct payloads and write them to their `outbox/`. The harness handles delivery. Here's the pattern from [`src/shared/agentProvider.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/shared/agentProvider.ts) (line 123):

```typescript
import { writeFileSync } from 'fs';
import { join } from 'path';

// Construct the message payload
const payload = {
  to: 'agent-42',
  act: 'request',
  subject: 'Fetch latest sales data',
  body: 'Please retrieve the CSV from the data lake.',
  conversation: 'sales-report-2024',
};

// Write to the agent's outbox (the harness will deliver it)
const outboxDir = join(__dirname, '..', 'agents', 'my-agent', 'outbox');
writeFileSync(join(outboxDir, `${Date.now()}.json`), JSON.stringify(payload, null, 2));

```

The `Date.now()` prefix ensures unique filenames and provides rough ordering. The harness polls or watches these directories via the logic registered in [`src/main/index.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/index.ts) at line 2147.

## Receiving and Processing Inbound Messages

At task startup, agents scan their `inbox/` for pending messages:

```typescript
import { readdirSync, readFileSync } from 'fs';
import { join } from 'path';

const inboxDir = join(__dirname, '..', 'agents', 'my-agent', 'inbox');
for (const file of readdirSync(inboxDir)) {
  if (file.endsWith('.json')) {
    const msg = JSON.parse(readFileSync(join(inboxDir, file), 'utf8'));
    console.log('Received:', msg);
    // Process the message …
    // Move to `.done/` after handling
  }
}

```

After processing, agents move handled files to `inbox/.done/` to prevent reprocessing. This archive enables debugging and replay scenarios.

## Trigger Modes: Controlling Message Flow Permissions

The **trigger system** in [`src/shared/triggers.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/shared/triggers.ts) (line 24) implements three strictness levels that govern which `act` types the harness permits:

- **`strict`** – Only explicit directives (`request`, `propose`) are accepted; informational messages are blocked unless whitelisted.
- **`allow-all`** – Both directives and `inform`, `query`, and conversation metadata flow without restriction.
- **`communication-only`** – Only informational messages pass automatically; directives require explicit human approval through the UI.

These modes enable deployments ranging from fully autonomous operation (`allow-all`) to human-in-the-loop governance (`communication-only`). The harness evaluates triggers before moving any file from `outbox/` to `inbox/`.

## Why File-Based Communication Beats Network Sockets

The **Munder Difflin communication protocol** prioritizes these properties over traditional IPC:

| Property | File-Based Hive | Network Sockets |
|----------|---------------|---------------|
| Durability | Automatic via Git | Requires custom logging |
| Debugging | Direct file inspection | Packet capture required |
| Replay | Checkout prior commit | Complex state restoration |
| Security | Filesystem ACLs | Firewall + TLS management |
| Determinism | Single harness serializes all IO | Concurrent connections race |

The harness's exclusive control of Git operations means every message produces a versioned, timestamped record. Developers can `git checkout` any prior state and replay agent behavior exactly.

## Summary

- The **file-based Hive protocol** routes all agent communication through `outbox/` and `inbox/` directories managed by a central harness.
- [`src/main/hive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/hive.ts) defines the message schema and implements the routing logic, with auto-populated fields for `id`, `from`, `hops`, and timestamps.
- [`src/shared/triggers.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/shared/triggers.ts) enforces `strict`, `allow-all`, and `communication-only` modes that filter messages by `act` type.
- Agents write JSON to their own `outbox/`; the harness alone moves files between agents, guaranteeing race-free coordination.
- All communication persists in Git, enabling debugging, audit, and replay without external infrastructure.

## Frequently Asked Questions

### What file format does the Munder Difflin protocol use?

The protocol uses **JSON files with a `.json` extension**. Any filename is valid—the harness detects new files by filesystem events and moves them regardless of naming convention. Message content must validate against the schema in [`PROTOCOL.md`](https://github.com/chaitanyagiri/munder-difflin/blob/main/PROTOCOL.md), with required fields `to`, `act`, `subject`, and `body`.

### Can agents communicate directly without the harness?

No. The **single-writer rule** prohibits agents from accessing other agents' directories. Agents write only to their own `outbox/`, and the harness exclusively performs cross-directory file operations. This architectural constraint prevents race conditions and ensures all communication is logged through Git.

### What are the valid values for the `act` field?

Per [`src/main/hive.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/src/main/hive.ts), the **speech act types** are: `request`, `inform`, `propose`, `query`, `agree`, `refuse`, and `done`. These map to standard FIPA agent communication semantics. The [`triggers.ts`](https://github.com/chaitanyagiri/munder-difflin/blob/main/triggers.ts) module classifies `request`, `propose`, and `query` as directives requiring potential approval, while `inform` and `done` are informational.

### How does the protocol handle message ordering?

Timestamps provide **rough ordering**, but the protocol does not guarantee strict FIFO delivery. Agents should use the `conversation` field to thread related messages and `in_reply_to` to establish causal relationships. For deterministic replay, Git commit ordering serves as the ground truth for message sequence.