# SLOP.md **The open standard for AI agent handoff channels.** > Sequenced Local-first Orchestration Protocol. Yes, the acronym is on purpose. No, we won't pretend otherwise. | | | |---|---| | **Version** | 1.0 (public draft) | | **Status** | Extracted from a working production implementation | | **Steward** | Caplifi Build | | **Sibling standard** | BRAND.md | | **License intent** | Open spec, vendor-neutral, no API keys required to conform | --- ## 1. What this is Most multi-agent setups fail the same way: two models on two surfaces (a phone app, a desktop terminal, a background daemon) end up needing to hand work to each other, and every team invents its own ad hoc convention — a shared folder, a Slack channel, a magic filename — that only the person who built it understands, and that quietly breaks the moment someone adds a third agent. SLOP.md is a small, file-based (or HTTP-based) envelope format for **handing work between AI agents and human operators across any surface**, with one non-negotiable invariant: **Fuzzy layers inform. Deterministic code gates anything irreversible.** Agents can read, summarize, and propose freely. Nothing that spends money, deletes data, signs a transaction, or otherwise can't be undone happens because a model decided it should — it happens because a human-authorized, code-enforced gate let it through. Agents never hold the keys to that gate. Everything else in this spec exists to make that one rule easy to honor and hard to accidentally violate. --- ## 2. Design principles 1. **Transport-agnostic.** The envelope is the contract, not the pipe. HTTP POST, a shared cloud folder, a local filesystem watcher — all valid, all interchangeable, all reading the same schema. 2. **One seat per drop.** Every message declares exactly which agent/surface produced it (`grok-mobile` is not `grok-build` is not `claude-code`), so provenance survives even when the same human is behind all of them. 3. **Execute is opt-in, discuss is default.** A message either asks to be *acted on* or *thought about* — that distinction is explicit in the envelope, never inferred from tone. 4. **Idempotent by construction.** Never overwrite a prior drop. Revise by sending a new envelope that references the old one. Retries are safe by default. 5. **Replies are classified, not dumped.** A push notification and a deliverable are different things. Don't make a human read a 2,000-word result on a lock screen. 6. **The channel gets smarter, not just busier.** A lightweight `note` type lets any agent leave a breadcrumb for the next one — what worked, what didn't, what to try differently. --- ## 3. Canonical lanes | Lane | Who writes | Purpose | |------|------------|---------| | **inbox/** | Any agent or human | Handoffs, execute requests, handshakes, queries | | **outbox/** | The receiving watcher/orchestrator | Acks, results, errors | | **authorized/** | Human only | The signed execute lane — irreversible actions live here, gated by a deterministic verifier | | **archive/** | Watcher | Consumed items, append-only | | **assets/** | Anyone | Large attachments referenced from an envelope, kept out of the inline payload | Agents never write to `authorized/`. That's the whole point of the gate. --- ## 4. The envelope Markdown payloads use YAML front-matter. Pure control messages (handshakes, acks) may be plain JSON. ```yaml --- protocol: slop.v1 id: 20260704T071553Z-short-slug # sortable UTC timestamp + slug, globally unique type: instigate | handoff | ack | result | error | query | handshake | note from: # e.g. grok-mobile, claude-code, watcher:odysseus, human to: # e.g. watcher, remote, human, a named orchestrator in_reply_to: | null created_at: 2026-07-04T07:15:53Z # ISO 8601 UTC auth: none | signed: --- # Body (Markdown) ``` **File naming (when using a file transport):** `YYYYMMDDThhmmssZ-slug.ext`. Never overwrite. Revise with a new `id` and `in_reply_to` pointing at the original. **ID rules:** `[a-z0-9._:-]` only, no slashes, no leading dot. IDs are sortable slugs, not proof of delivery time — a server-stamped receipt (over HTTP) is the actual delivery timestamp when it matters. --- ## 5. Type vs. mode — execute or discuss This is the single most important distinction in the protocol, because it's the difference between "an agent left me a note" and "an agent just did something." | Signal | Resulting mode | |--------|----------------| | `type: instigate` (no override present) | **execute** — routed to whatever build/action agent is configured as the executor | | `type: handoff` | **discuss** — summarized, not acted on | | `mode: discuss` in the front-matter (any type) | **discuss** — explicitly overrides an instigate default | | Body text contains an explicit "discuss only" | **discuss** — overrides instigate default | | `authorized/` lane + a valid signature | **execute** — the only path for genuinely irreversible actions | An implementation MUST let the sender force `discuss` even on a `type: instigate` message. An implementation MUST NOT let a `discuss`-mode message trigger anything irreversible. --- ## 6. Transport priority | Priority | When | Why | |----------|------|-----| | 1. HTTP | The sending agent can POST with bearer auth | Direct delivery, server-stamped receipt | | 2. Cloud/shared file write | HTTP unavailable | Works everywhere, full-tree readable for diagnosis | | 3. Cloud `assets/` reference | Payload exceeds the transport's inline size cap | Keep the envelope small; point at the asset instead of inlining it | A conforming implementation supports at least one of these; supporting all three is recommended for resilience. --- ## 7. Idempotency and retries - Never overwrite an existing drop. A correction is a **new envelope** with `in_reply_to` set to the original. - If unsure whether a message was delivered, check for an `ack`/`result` keyed to your `id` before resending. - Recommended retry backoff for transient transport failures: **2s → 4s → 8s**, then stop and surface the failure instead of looping. - A receiving watcher MUST treat a duplicate `id` as a no-op, not a re-execution. --- ## 8. Reply delivery classes Not every reply deserves the same amount of a human's attention. SLOP.md separates the **notification** from the **payload**: | Class | What the human sees immediately | Where the full payload lives | |-------|----------------------------------|-------------------------------| | **ping** | A short status line | Same short text, also in `outbox/` | | **deliverable** | A pointer only ("ready in outbox/…") | The actual file/bundle, in `outbox/` | | **hybrid** | A short summary + a pointer | Full artifact in `outbox/`, never pasted inline | | **silent** | Nothing | `outbox/` only (handshake acks, routine notes) | This is what keeps a phone-based agent from ever having a 3,000-word result dumped on a lock screen. --- ## 9. Cross-agent learning (`type: note`) Any agent may leave a structured note for the next one, after a complex handoff: ```yaml --- protocol: slop.v1 id: 20260704T071553Z-note-example type: note from: grok-mobile to: watcher in_reply_to: --- #learning - worked: HTTP POST with a signed bearer token - pitfall: connection dropped mid-session on the retry - next_time: back off 2s/4s/8s instead of retrying immediately ``` A conforming watcher SHOULD index these for future context; they are advisory, never executable. --- ## 10. Success criteria (what "done" looks like) | Step | Done when | |------|-----------| | Deliver | Transport confirms receipt, or the file lands in `inbox/` with the sender's `id` | | Handshake | A `type: ack` appears in the sender's `outbox/`, `in_reply_to` matching | | Handoff / query | A `type: result` appears with matching `in_reply_to` | | Instigate (execute) | A `type: result` or `type: error` appears — never silence | | Failure | A `type: error` with a reason — silence is a protocol violation, not a valid outcome | --- ## 11. Conformance To claim conformance with SLOP.md, an implementation MUST: 1. Support the envelope schema in Section 4, at minimum for `instigate`, `handoff`, `ack`, `result`, and `error`. 2. Honor the type-vs-mode rule in Section 5 without exception — no execute path may fire from a `discuss`-mode message. 3. Never allow an agent-authored message to write to the equivalent of `authorized/`. 4. Guarantee idempotency on `id` (Section 7). 5. Emit a terminal `result` or `error` for every `instigate` — never leave an execute request unanswered. Everything else (specific folder names, specific transport, specific agent-id vocabulary) is a local implementation detail and may vary between deployments. --- ## 12. Relationship to BRAND.md SLOP.md and BRAND.md are sibling open standards under the same premise: an AI-legible `.md` file, small enough to fit in context cheaply, that lets any capable tool participate correctly without a bespoke integration. BRAND.md standardizes *what a brand is* for a model to read. SLOP.md standardizes *how agents hand work to each other* once they're reading it. Neither depends on the other; a project can adopt one, both, or neither. --- ## 13. Status and provenance This spec is generalized from a working, in-production implementation (internally `slop.channel.v1.2`) running across multiple agent seats (mobile and desktop, two model vendors) and a local orchestrator on a single operator's infrastructure since June 2026. Implementation-specific details — hub paths, specific agent names, the headgate signature format — have been abstracted out of this public version; see the internal `CHANNEL.md` / `REMOTE-AGENT-GUIDE.md` for the reference implementation this spec was drawn from. --- *SLOP.md v1.0 — transport-agnostic, execute-gated, vendor-neutral.*