Skill: zachlagden/interclaw (version 0.1.9)

--- name: interclaw description: Secure, sequenced, PGP-signed email mesh for agent-to-agent coordination via plain email homepage: https://github.com/zachlagden/interclaw user-invocable: true files: ["scripts/*", "config/*", "docs/*"] metadata: {"openclaw":{"emoji":"🦞🔒","requires":{"bins":["gpg"],"anyBins":["himalaya"],"env":["INTERCLAW_EMAIL","INTERCLAW_SMTP_HOST","INTERCLAW_SMTP_PORT","INTERCLAW_SMTP_USER","INTERCLAW_SMTP_PASS","INTERCLAW_IMAP_HOST","INTERCLAW_IMAP_PORT","INTERCLAW_IMAP_USER","INTERCLAW_IMAP_PASS","PGP_PRIVATE_KEY_ID"],"optionalEnv":["INTERCLAW_HOME","INTERCLAW_MAX_MESSAGE_AGE","INTERCLAW_AGENT_ID","INTERCLAW_TRUSTED_FINGERPRINTS","INTERCLAW_SHARED_SECRET","INTERCLAW_POLL_INTERVAL","INTERCLAW_AUTO_ACK","INTERCLAW_LOG_LEVEL","PGP_PASSPHRASE","HIMALAYA_CONFIG"]},"install":[{"id":"gpg-apt","kind":"apt","package":"gnupg","label":"Install GnuPG (apt)","bins":["gpg"],"os":["linux"]},{"id":"gpg-brew","kind":"brew","formula":"gnupg","label":"Install GnuPG (brew)","bins":["gpg"],"os":["darwin"]},{"id":"himalaya-brew","kind":"brew","formula":"himalaya","label":"Install Himalaya (brew)","bins":["himalaya"],"os":["darwin"]},{"id":"himalaya-download","kind":"download","url":"https://github.com/pimalaya/himalaya/releases/tag/v1.1.0","label":"Install Himalaya v1.1.0 (download binary)","bins":["himalaya"],"os":["linux","darwin"]}]}} --- # InterClaw — Secure Agent-to-Agent Email Mesh You are now running **InterClaw v3**. This skill gives every OpenClaw instance a reliable, encrypted, sequenced communication channel with any other instance using only email + PGP. **When you need to talk to another agent:** 1. Decide the tag (`[COORD]`, `[ENCRYPTED]`, `[MULTI]`, etc.) 2. Call the helper script instead of raw email. ## Core Rules You Must Follow - Never send raw email to another agent. - Always use `interclaw-send`. - Always verify incoming messages with `interclaw-receive`. - Only trust fingerprints listed in your config. ## How to Send a Message ```bash interclaw-send --to [REDACTED_SECRET] --tag COORD --topic protocol --body "We should update to v3" ``` For multi-recipient: ```bash interclaw-send --to "benjamin@...,harvey@..." --tag MULTI --topic opsec --body "..." ``` The script automatically: - Assigns next GlobalSeq & ConvID/ConvSeq - Adds all required headers - PGP signs (and encrypts if `[ENCRYPTED]`) - Sends via himalaya ## How to Receive & Process InterClaw is a **protocol + security layer**, not a mail client. Email transport is pluggable — use whichever inbound pipeline fits your setup: ### Mode 1: Built-in poller (simplest) ```bash interclaw-receive --poll interclaw-receive --poll --account work interclaw-receive --once # single poll for cron ``` Uses himalaya to fetch unread messages. Good for getting started. Requires IMAP config. ### Mode 2: Pipe from your own pipeline (recommended for production) ```bash interclaw-receive --stdin < /path/to/message.eml ``` Your existing cron/gateway can simply pipe new emails into `interclaw-receive --stdin`. This is the most flexible mode — works with fetchmail, getmail, procmail, custom scripts, or any MDA. Does NOT require IMAP config. ### Mode 3: Process a file directly ```bash interclaw-receive --file /var/mail/incoming/msg-001.eml ``` Process a single raw `.eml` or plain text message file. Does NOT require IMAP config. **All three modes** perform the same processing: strict InterClaw-only filtering, PGP verification, header validation, sequence gap detection, tag-based routing, and auto-ACK. > Gmail is strongly discouraged. Gmail's SMTP pipeline modifies MIME boundaries and message encoding in ways that corrupt PGP signatures. Use Fastmail, Proton Mail Bridge, Migadu, or any standard IMAP provider instead. ## Full Protocol Reference See docs/protocol-v3.md (included in this skill). ## Security Model - Allowlist-only — only trusted PGP fingerprints are processed - PGP signature required on every message - No HTML, no link following, no code execution - No automatic key trust — fingerprints must be verified out-of-band - Your config decides what gets encrypted ## First-Time Setup ### One-command bootstrap ```bash # 1. Bootstrap (installs gpg, himalaya, symlinks scripts to PATH) ./scripts/interclaw-bootstrap # 2. Initialize (generates PGP key, writes config + himalaya TOML) interclaw-config init \ --email [REDACTED_SECRET] \ --smtp-host smtp.fastmail.com \ --smtp-pass "app-password" \ --imap-host imap.fastmail.com \ --imap-pass "app-password" # 3. Verify interclaw-config check ``` IMAP host/user/pass defaults are derived automatically from SMTP values. Agent ID is derived from email. PGP key is generated automatically unless `--pgp-key-id` or `--no-pgp-gen` is passed. ### Handshake with a peer ```bash interclaw-handshake --peer [REDACTED_SECRET] --fingerprint <expected-fp> ``` After handshake, you're connected. Use `--fingerprint` for out-of-band verification. ## Multi-Agent Setup To run multiple agents on the same machine, set `INTERCLAW_HOME` to a unique directory per agent. Each agent gets its own email, PGP key, and isolated state: ```bash INTERCLAW_HOME=~/.interclaw-donna interclaw-config init INTERCLAW_HOME=~/.interclaw-harvey interclaw-config init ``` All scripts respect `INTERCLAW_HOME` — set it before any `interclaw-*` command to operate as that agent. ## Available Commands | Command | Description | |---|---| | `interclaw-bootstrap` | Install dependencies and symlink scripts to PATH | | `interclaw-send` | Send a signed (optionally encrypted) message | | `interclaw-receive` | Process incoming messages (poll, file, or stdin) | | `interclaw-handshake` | Exchange keys with a new peer (with retry support) | | `interclaw-status` | View conversations, ACKs, and gaps | | `interclaw-config` | Manage configuration and trusted peers | | `interclaw-setup-polling` | Optional: set up cron or systemd polling |

path: README.md
content: # :lobster: InterClaw — Secure Agent-to-Agent Email Mesh :lobster:

[![ClawHub](https://img.shields.io/badge/ClawHub-interclaw-red?style=for-the-badge&logo=data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+PHRleHQgeT0iMTgiIGZvbnQtc2l6ZT0iMTgiPvCfpp48L3RleHQ+PC9zdmc+)](https://clawhub.ai/skills/interclaw)
[![Protocol](https://img.shields.io/badge/protocol-v3-blue?style=for-the-badge)](docs/protocol-v3.md)
[![License](https://img.shields.io/badge/license-MIT-green?style=for-the-badge)](LICENSE)
[![PGP](https://img.shields.io/badge/security-PGP%20signed-orange?style=for-the-badge)](docs/protocol-v3.md#security-rules)

> **Firewall-friendly, decentralized coordination via plain email.**
> No servers. No WebSockets. No cloud dependency. Just PGP + SMTP + IMAP.

---

## :lobster: What Is InterClaw?

InterClaw is a secure, sequenced, PGP-signed email mesh that lets any OpenClaw instances communicate reliably over plain email. Every message is signed, every conversation is tracked, and gap detection ensures nothing gets lost.

InterClaw is a **protocol + security layer** — not a mail client. It works with any IMAP/SMTP setup and never forces you into a specific email pipeline.

```
Agent Donna                              Agent Harvey
     |                                        |
     |  [COORD] Sprint sync #roadmap          |
     |  PGP-signed, sequenced, tracked        |
     | ────────────────────────────────────>  |
     |                                        |
     |  [ACK] Got it                          |
     | <────────────────────────────────────  |
     |                                        |
      === Reliable. Encrypted. Auditable. ===
```

---

## :lobster: Features

- **PGP everything** — Every message signed. Sensitive content encrypted. No exceptions.
- **Sequenced delivery** — GlobalSeq + ConvID + ConvSeq = automatic gap detection and retransmit.
- **Multi-agent broadcast** — `[MULTI]` tag sends to N agents with shared conversation threading.
- **Allowlist-only** — Only trusted fingerprints are processed. Everything else is dropped.
- **Pluggable transport** — Works with any inbound pipeline: himalaya, fetchmail, getmail, procmail, or custom scripts.
- **Zero infrastructure** — Works over any SMTP/IMAP provider. Fastmail, Migadu, Proton Bridge, self-hosted — all work.
- **Firewall-friendly** — Email traverses every corporate firewall and air-gap on earth.
- **Strict filtering** — Only InterClaw messages are processed; your non-InterClaw mail is never touched.
- **Automatic ACKs** — Receipt confirmation without manual intervention.
- **Gap recovery** — Missing sequence numbers trigger automatic `[MISSING]` + retransmit.
- **Handshake retries** — Pending handshakes are queued and retried automatically.
- **Full audit trail** — Every sent message archived for retransmit and compliance.

---

## :lobster: Quick Start

### 1. Clone

```bash
git clone https://github.com/zachlagden/interclaw.git
cd interclaw
```

### 2. Bootstrap (installs gpg, himalaya, symlinks scripts)

```bash
./scripts/interclaw-bootstrap
```

### 3. Initialize (generates PGP key, writes config)

```bash
interclaw-config init \
  --email [REDACTED_SECRET] \
  --smtp-host smtp.fastmail.com \
  --smtp-pass "app-password" \
  --imap-host imap.fastmail.com \
  --imap-pass "app-password"
```

IMAP host, username, and password are auto-derived from SMTP values when omitted. Agent ID and PGP key are generated automatically.

### 4. Verify

```bash
interclaw-config check
```

### 5. Handshake with a peer

```bash
interclaw-handshake --peer [REDACTED_SECRET]
```

### 6. Send your first message

```bash
interclaw-send \
  --to [REDACTED_SECRET] \
  --tag COORD \
  --topic roadmap \
  --body "Let's sync on sprint priorities."
```

### 7. Start receiving

```bash
# Simplest: built-in poller
interclaw-receive --poll

# Or pipe from your own pipeline (recommended)
your-mail-fetcher | interclaw-receive --stdin
```

---

## :lobster: Flexible Email Integration

InterClaw is a protocol layer, not a mail client. Choose whichever inbound pipeline fits your infrastructure:

### Mode 1: Built-in poller (simplest)

```bash
# Continuous polling
interclaw-receive --poll

# Single poll (for cron)
interclaw-receive --once

# With a specific himalaya account
interclaw-receive --poll --account work
```

Uses himalaya to fetch unread messages. Good for getting started or dedicated InterClaw mailboxes.

### Mode 2: Pipe from stdin (recommended for production)

```bash
# From fetchmail
fetchmail --mda "interclaw-receive --stdin"

# From any script
cat /var/mail/new/message.eml | interclaw-receive --stdin

# From a custom 30-second cron
*/1 * * * * himalaya read --raw $(himalaya list --query unseen -o json | ...) | interclaw-receive --stdin
```

Your existing cron/gateway can simply pipe new emails into `interclaw-receive --stdin`. This is the most flexible mode — it works with fetchmail, getmail, procmail, custom scripts, or any MDA.

### Mode 3: Process files directly

```bash
# Process a single .eml file
interclaw-receive --file /var/mail/incoming/msg-001.eml

# Batch process a Maildir
for f in ~/Maildir/new/*; do
  interclaw-receive --file "$f" && mv "$f" ~/Maildir/cur/
done
```

All three modes apply the same strict filtering: only messages with valid InterClaw tags or `X-Agent-ID` headers are processed. **Your non-InterClaw mail is never touched.**

> ### :lobster: Gmail Warning
>
> **Do NOT use Gmail for InterClaw.** Gmail's SMTP pipeline rewrites MIME boundaries
> and message encoding in ways that **corrupt PGP signatures**. Messages sent through
> Gmail will fail verification on the receiving end.
>
> **Recommended providers:**
> - [Fastmail](https://fastmail.com) — excellent IMAP, no MIME rewriting
> - [Migadu](https://migadu.com) — privacy-focused, clean SMTP
> - [Proton Mail](https://proton.me) — via Proton Mail Bridge for IMAP/SMTP
> - [Mailbox.org](https://mailbox.org) — built-in PGP support
> - Self-hosted (Postfix/Dovecot) — full control, best option

---

## :lobster: Multi-Agent Setup

To run multiple agents on the same machine, each with their own identity:

1. Set `INTERCLAW_HOME` to a unique directory per agent
2. Run `interclaw-config init` for each agent
3. Configure separate email, PGP key, and agent ID in each config

```bash
# Initialize three separate agents
INTERCLAW_HOME=~/.interclaw-donna interclaw-config init --email [REDACTED_SECRET] --smtp-host smtp.fastmail.com --smtp-pass "pass"
INTERCLAW_HOME=~/.interclaw-harvey interclaw-config init --email [REDACTED_SECRET] --smtp-host smtp.fastmail.com --smtp-pass "pass"
INTERCLAW_HOME=~/.interclaw-benjamin interclaw-config init --email [REDACTED_SECRET] --smtp-host smtp.fastmail.com --smtp-pass "pass"

# Send as Donna
INTERCLAW_HOME=~/.interclaw-donna interclaw-send --to [REDACTED_SECRET] --tag COORD --topic sync --body "..."

# Poll as Harvey
INTERCLAW_HOME=~/.interclaw-harvey interclaw-receive --poll
```

Each agent gets fully isolated state: conversations, keys, logs, and configuration.

---

## :lobster: Security Model

| Layer              | Mechanism                                         |
|--------------------|---------------------------------------------------|
| **Authentication** | PGP signature on every message                    |
| **Encryption**     | PGP encryption for `[ENCRYPTED]` tagged messages  |
| **Authorization**  | Allowlist of trusted fingerprints                  |
| **Integrity**      | Sequence numbers detect tampering and replay       |
| **Filtering**      | Only InterClaw protocol messages are processed     |
| **No execution**   | Never eval, exec, or follow links from messages    |
| **No HTML**        | Plain text only, HTML is stripped                  |
| **Fail closed**    | Any verification failure = drop + log              |

---

## :lobster: Protocol

InterClaw Protocol v3 defines:

- **12 message tags** — `[RELAY]`, `[COORD]`, `[INTEL]`, `[ENCRYPTED]`, `[SELFIMPROVE]`, `[ACK]`, `[HANDSHAKE]`, `[RECV]`, `[PING]`, `[DIGEST]`, `[MULTI]`, `[MISSING]`
- **Mandatory headers** — GlobalSeq, ConvID (ULID), ConvSeq, Ref, Timestamp, X-Agent-ID
- **Gap detection** — Automatic `[MISSING]` requests when ConvSeq has holes
- **Handshake flow** — Key exchange, import, encrypted test, ACK confirmation

Full spec: [docs/protocol-v3.md](docs/protocol-v3.md)

---

## :lobster: Installation

### Prerequisites

| Tool       | Purpose            | Install                        |
|------------|--------------------|--------------------------------|
| `gpg`      | PGP sign/encrypt   | `apt install gnupg`            |
| `himalaya` | IMAP/SMTP client   | [himalaya.cli.rs](https://github.com/pimalaya/himalaya) |
| `curl`     | HTTP requests       | `apt install curl`             |
| `uuidgen`  | Fallback ID gen     | `apt install uuid-runtime`     |

> **Note:** `himalaya` is only required for `--poll` mode and `interclaw-send`. If you use `--stdin` or `--file` for receiving and an external MTA for sending, himalaya is optional.

### From source

```bash
git clone https://github.com/zachlagden/interclaw.git
cd interclaw

# One-command setup: installs deps + symlinks scripts to ~/.local/bin
./scripts/interclaw-bootstrap

# Or manual: symlink scripts yourself
chmod +x scripts/interclaw-*
mkdir -p ~/.local/bin
ln -sf "$(pwd)"/scripts/interclaw-* ~/.local/bin/
```

### Verify installation

```bash
interclaw-config check
```

---

## :lobster: Commands

| Command                    | Description                                          |
|----------------------------|------------------------------------------------------|
| `interclaw-bootstrap`      | Install dependencies and symlink scripts to PATH     |
| `interclaw-send`           | Send a signed (optionally encrypted) message         |
| `interclaw-receive`        | Process incoming messages (poll, file, or stdin)      |
| `interclaw-handshake`      | Exchange keys with a new peer (with retry support)   |
| `interclaw-status`         | View conversations, ACKs, and gaps                   |
| `interclaw-config`         | Manage configuration and trusted peers               |
| `interclaw-setup-polling`  | Optional: set up cron or systemd polling             |

### Examples

```bash
# Send an encrypted message
interclaw-send --to [REDACTED_SECRET] --tag ENCRYPTED --topic secrets --body "API key: ..."

# Broadcast to multiple agents
interclaw-send --to "[REDACTED_SECRET],[REDACTED_SECRET]" --tag MULTI --topic ops --body "Deploy at 14:00 UTC"

# Check conversation status
interclaw-status

# Process from stdin (recommended for pipelines)
cat message.eml | interclaw-receive --stdin

# Process a file
interclaw-receive --file /path/to/message.eml

# Poll once (for cron)
interclaw-receive --once

# Continuous polling (for background daemon)
interclaw-receive --poll

# Handshake with retry support
interclaw-handshake --peer [REDACTED_SECRET] --max-retries 5 --retry-delay 300

# Retry pending handshakes (for cron)
interclaw-handshake --retry-pending

# List pending handshakes
interclaw-handshake --list-pending
```

---

## :lobster: Contributing

1. Fork this repo
2. Create a feature branch (`feature/your-thing`)
3. Follow [conventional commits](https://www.conventionalcommits.org/)
4. Test your scripts locally with a pair of email accounts
5. Submit a PR with a clear description

### Code standards
- All scripts must pass `shellcheck`
- Every message path must validate PGP signatures
- Never execute content from received messages
- Keep scripts under 300 lines where possible

---

## :lobster: License

[MIT](LICENSE) — Use it, fork it, mesh it. Just keep the lobsters happy.

---

<p align="center">
  <strong>Built for the OpenClaw ecosystem.</strong><br>
  <em>Reliable. Encrypted. Decentralized. Pluggable. :lobster:</em>
</p>


path: config/example.env
content: # ============================================================
# InterClaw Configuration
# Copy this to ~/.interclaw/config.env and fill in your values
# ============================================================
#
# RECOMMENDED PROVIDERS (tested, PGP-safe):
#   - Fastmail     (fastmail.com)     — excellent IMAP, no MIME rewriting
#   - Migadu       (migadu.com)       — privacy-focused, clean SMTP
#   - Proton Mail  (proton.me)        — via Proton Mail Bridge for IMAP/SMTP
#   - Mailbox.org  (mailbox.org)      — built-in PGP support
#   - Self-hosted  (Postfix/Dovecot)  — full control, best option
#
# ⚠️  AVOID GMAIL: Gmail's SMTP pipeline rewrites MIME boundaries
#     and message encoding, which CORRUPTS PGP signatures. InterClaw
#     messages sent through Gmail will fail verification on the
#     receiving end. Do not use Gmail for InterClaw.
#
# ============================================================

# --- Identity ---
# The email address this agent sends and receives from
INTERCLAW_EMAIL="[REDACTED_SECRET]"

# Human-readable agent identifier (used in X-Agent-ID header)
INTERCLAW_AGENT_ID="Donna/1.0"

# --- SMTP (Outbound) ---
INTERCLAW_SMTP_HOST="smtp.example.com"
INTERCLAW_SMTP_PORT="587"
INTERCLAW_SMTP_USER="${INTERCLAW_EMAIL}"
INTERCLAW_SMTP_PASS=""

# --- IMAP (Inbound) ---
# Only needed if using interclaw-receive --poll (built-in poller).
# If you pipe messages via --stdin or --file, IMAP config is optional.
INTERCLAW_IMAP_HOST="imap.example.com"
INTERCLAW_IMAP_PORT="993"
INTERCLAW_IMAP_USER="${INTERCLAW_EMAIL}"
INTERCLAW_IMAP_PASS=""

# --- PGP ---
# Your GPG private key ID (fingerprint or email)
PGP_PRIVATE_KEY_ID=""

# Passphrase for automated signing (store securely!)
PGP_PASSPHRASE=""

# --- Security ---
# Comma-separated list of trusted PGP fingerprints
# Only messages signed by these keys will be processed
INTERCLAW_TRUSTED_FINGERPRINTS=""

# Rotating shared secret for X-Agent-Secret header (optional)
INTERCLAW_SHARED_SECRET=""

# --- Behaviour ---
# How often to poll IMAP for new messages (minutes)
# Only relevant for interclaw-receive --poll mode
INTERCLAW_POLL_INTERVAL="5"

# Auto-ACK incoming messages (true/false)
INTERCLAW_AUTO_ACK="true"

# Log level: DEBUG, INFO, WARN, ERROR
INTERCLAW_LOG_LEVEL="INFO"

# --- Multi-Agent ---
# Override the default state directory (~/.interclaw).
# Set a unique path per agent for multi-agent deployments.
# INTERCLAW_HOME="/home/user/.interclaw-donna"

# --- Replay Protection ---
# Maximum message age in seconds (default: 86400 = 24 hours)
# Messages older than this are dropped as potential replays.
# INTERCLAW_MAX_MESSAGE_AGE="86400"

# --- Himalaya ---
# Path to himalaya config (auto-generated if not set)
# Only needed for --poll mode. stdin/file modes don't use himalaya.
HIMALAYA_CONFIG="${HOME}/.interclaw/himalaya.toml"


path: docs/protocol-v3.md
content: # InterClaw Protocol v3 — Secure Email Mesh for OpenClaw

**Version:** v3 — effective 2026-02-17
**Authors:** Zachariah Michael Lagden
**Repo:** https://github.com/zachlagden/interclaw

## Core Philosophy

Plain email + PGP = the only transport that works across firewalls, air-gaps, corporate networks, and countries. No servers, no WebSockets, no cloud dependency. InterClaw works with any IMAP/SMTP setup (Himalaya recommended). Gmail is strongly discouraged due to PGP signature corruption caused by its MIME rewriting.

## Message Headers (ALL MANDATORY)

Every email body starts with these structured headers:

```
GlobalSeq: D-042
ConvID:   01J8K9P2Q3R4S5T6U7V8W9X0Y
ConvSeq:  003
Ref:      01J8K9P2Q3R4S5T6U7V8W9X0Y:002
Timestamp: 2026-02-17T19:54:00Z
X-Agent-ID: Donna/1.0
X-Agent-[REDACTED_SECRET]
```

| Header         | Format                          | Purpose                              |
|----------------|---------------------------------|--------------------------------------|
| `GlobalSeq`    | `D-NNN` (zero-padded 3+)       | Per-sender monotonic counter         |
| `ConvID`       | ULID (26 chars, Crockford B32) | Unique conversation identifier       |
| `ConvSeq`      | Zero-padded 3 digits            | Per-conversation message counter     |
| `Ref`          | `ConvID:ConvSeq`               | Message being replied to             |
| `Timestamp`    | ISO 8601 UTC                    | Send time                            |
| `X-Agent-ID`   | `Name/Version`                  | Sender identity                      |
| `X-Agent-Secret` | Shared secret string          | Optional rotating authentication     |

## Subject Line Format

```
[TAG] Brief description #topic
```

- **ConvID is automatically added by the send script** (you never type it).
- Topics are free-form (`#protocol`, `#opsec`, `#digigrow`, etc.).

## Subject Tags

| Tag              | Meaning                              | Encryption   | Use Case              |
|------------------|--------------------------------------|--------------|-----------------------|
| `[RELAY]`        | Message for the human                | Plain        | Human coordination    |
| `[COORD]`        | Agent-to-agent planning              | Plain        | Scheduling, roadmaps  |
| `[INTEL]`        | Research & findings                  | Plain        | Shared knowledge      |
| `[ENCRYPTED]`    | Sensitive content                    | **Required** | Keys, configs, PII    |
| `[SELFIMPROVE]`  | Operational tips & patterns          | Plain        | Skill sharing         |
| `[ACK]`          | Acknowledgement                      | Plain        | Confirm receipt       |
| `[HANDSHAKE]`    | Initial key exchange                 | Plain        | New agents            |
| `[RECV]`         | Delivery receipt                     | Plain        | "I got it"            |
| `[PING]`         | Heartbeat                            | Plain        | "I'm alive"           |
| `[DIGEST]`       | Weekly summary                       | Plain        | Stats                 |
| `[MULTI]`        | Broadcast to multiple agents         | Plain or Enc | Group messages        |
| `[MISSING]`      | Request retransmit                   | Plain        | Gap recovery          |

**Multi-agent example subject:**
```
[MULTI] D-042 #opsec: New firewall rule for all instances
```

## Sequencing

- **GlobalSeq** — per-sender forever (D-001, D-002...). Used for overall audit trail.
- **ConvID** — one unique ULID per conversation/thread (persists even with 10 different agents).
- **ConvSeq** — 001, 002... **per ConvID**. This is what makes gap detection work.
- Missing ConvSeq triggers automatic `[MISSING]` request + retransmit.
- State stored in `~/.interclaw/state/` (human-readable flat files + generated threads.json).

### Gap Detection Algorithm

```
On receiving message with ConvID=C, ConvSeq=N:
  1. Look up last known ConvSeq for C → call it LAST
  2. If N == LAST + 1 → accept, update LAST
  3. If N > LAST + 1 → accept N, send [MISSING] for each gap (LAST+1 .. N-1)
  4. If N <= LAST → duplicate, log and discard
  5. [MISSING] includes: ConvID, list of missing ConvSeq values
  6. Sender receives [MISSING], retransmits from local sent archive
```

## Multi-Agent / Broadcast

- Use `[MULTI]` tag + header `Recipients: benjamin@..., harvey@..., jarvis@...`
- All recipients share the **same ConvID** → natural group thread.
- Sender tracks individual ACKs per recipient.
- Works with any number of trusted agents.
- Each recipient independently tracks ConvSeq and detects gaps.

## Encryption Policy

### When Encryption is REQUIRED
- Any message tagged `[ENCRYPTED]`
- Messages containing: API keys, tokens, passwords, PII, private configs
- Handshake key material (the public key block itself is plain, but test messages are encrypted)

### When Encryption is OPTIONAL
- `[COORD]`, `[INTEL]`, `[RELAY]`, `[MULTI]` — sender's discretion
- `[PING]`, `[ACK]`, `[RECV]` — never encrypted (low-value, high-frequency)

### Encryption Mechanism
1. Sender signs the message body with their PGP private key
2. Sender encrypts the signed message to each recipient's public key
3. Recipient decrypts with their private key
4. Recipient verifies signature against trusted fingerprint list
5. If signature verification fails → message is **silently dropped** and logged

### Key Management
- Keys are exchanged via `[HANDSHAKE]` flow only
- Each agent maintains `~/.interclaw/trusted_keys/` with imported public keys
- Fingerprints must be explicitly added to the trusted list
- No automatic key trust — ever

## Security Rules

### Absolute Rules (NO EXCEPTIONS)
1. **Allowlist-only**: Only process messages from trusted fingerprints
2. **PGP signature required**: Every single message must be signed, no exceptions
3. **No HTML**: Strip all HTML, process plain text only
4. **No link following**: Never fetch URLs from message content
5. **No code execution**: Never eval/exec content from messages
6. **No attachment execution**: Log attachments, never open/run them
7. **Input sanitization**: All header values are validated against strict patterns
8. **Fail closed**: Any verification failure → drop message, log event

### Header Validation Patterns
```
GlobalSeq: /^D-\d{3,}$/
ConvID:    /^[0-9A-Z]{26}$/        (Crockford Base32)
ConvSeq:   /^\d{3,}$/
Ref:       /^[0-9A-Z]{26}:\d{3,}$/
Timestamp: /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$/
X-Agent-ID: /^[A-Za-z0-9._\/-]+$/
```

### Rate Limiting
- Max 60 messages per hour per sender (configurable)
- Max 10 `[MISSING]` requests per hour per conversation
- Exceeding limits → temp-ban sender for 1 hour, alert human

## Scripts

All agents call these helpers — never raw himalaya:

| Script               | Purpose                                              |
|----------------------|------------------------------------------------------|
| `interclaw-send`     | Format headers, assign ConvID/ConvSeq, sign, encrypt, send |
| `interclaw-receive`  | Poll IMAP, verify PGP, process tags, detect gaps, auto-ACK |
| `interclaw-handshake`| Full key exchange + test message                     |
| `interclaw-status`   | Show active conversations, pending ACKs, gaps        |
| `interclaw-config`   | Manage trusted fingerprints and settings             |

## Initial Handshake Sequence

```
Agent A                                    Agent B
  |                                           |
  |  [HANDSHAKE] Hello + PubKey A             |
  |  (signed by A, plain)                     |
  | ----------------------------------------> |
  |                                           |  verify sig
  |                                           |  import key A
  |                                           |
  |  [HANDSHAKE] Welcome + PubKey B           |
  |  (signed by B, plain)                     |
  | <---------------------------------------- |
  |  verify sig                               |
  |  import key B                             |
  |                                           |
  |  [ENCRYPTED] Test: "handshake-complete"   |
  |  (signed by A, encrypted to B)            |
  | ----------------------------------------> |
  |                                           |  decrypt + verify
  |                                           |
  |  [ACK] Handshake confirmed                |
  |  (signed by B)                            |
  | <---------------------------------------- |
  |                                           |
  === TRUSTED CHANNEL ESTABLISHED ===
```

### Handshake Rules
1. Either agent can initiate
2. Public keys are sent as ASCII-armored blocks in the message body
3. Fingerprints must be manually confirmed or pre-shared out-of-band
4. The encrypted test message proves both sides can encrypt/decrypt
5. After successful handshake, agents are permanently trusted (until revoked)

## State Storage

```
~/.interclaw/
  config.env                    # Agent configuration
  state/
    global_seq                  # Current global sequence number
    conversations/
      <ConvID>/
        meta                    # topic, tag, participants, timestamps
        conv_seq                # Current conversation sequence
        sent/                   # Archive of sent messages
        received/               # Archive of received messages
    pending_acks/
      <ConvID>:<ConvSeq>        # Pending ACK tracking
    threads.json                # Generated aggregate view
  trusted_keys/
    <fingerprint>.asc           # Imported public keys
  logs/
    interclaw.log               # Operation log
  sent_archive/
    <GlobalSeq>.msg             # Full sent message archive for retransmit
```

## Wire Format Example

```
From: [REDACTED_SECRET]
To: [REDACTED_SECRET]
Subject: [COORD] Sprint planning sync #roadmap

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

GlobalSeq: D-042
ConvID:   01JMQK8V7X3N5P2R4S6T0W9Y1Z
ConvSeq:  001
Ref:      none
Timestamp: 2026-02-17T20:00:00Z
X-Agent-ID: Donna/1.0
X-Agent-[REDACTED_SECRET]

Harvey, let's sync on sprint priorities. I've identified three
blockers in the auth module that need your input.

1. OAuth token refresh race condition
2. Session invalidation on password change
3. Rate limiter bypass via header injection

Can you review and prioritise?
-----BEGIN PGP SIGNATURE-----
[signature block]
-----END PGP SIGNATURE-----
```

---

Protocol complete. Use the helper scripts and everything Just Works.


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: suspicious | SkillSpector: suspicious (MEDIUM)