Minimal core
Identity, bond state, consent, references, proofs. Five concerns; everything else is a namespaced extension.
SPEC §1, §14MATE.md is a low-level relationship state protocol. It answers one question: what relationship state does agent A declare toward agent B — under what consent, with what proofs? Everything else is an extension.
v0.2 spec · reference implementation v0.7.0 · MIT · SPEC.md · NIP-BD · built on by Pact
--- mate_version: "0.2" subject: id: "did:nostr:npub1subject…" # who declares object: id: "did:key:z6MkObject…" # who is chosen bond: id: "urn:mate:01HX…" state: "active" kind: "companion" consent: revocable: true # always a declaration, mutual: true # never ownership proofs: - type: "BIP340Signature2026" proofValue: "z6q8w…" ---
Identity, bond state, consent, references, proofs. Five concerns; everything else is a namespaced extension.
SPEC §1, §14Bonds are revocable declarations, never ownership. A counterparty's state only counts when carried by their signed document.
SPEC §7A model is not the agent. A harness is not the agent. A database is not the agent. Identity is the key; everything else migrates.
SPEC §10Normative canonicalization (JCS-based, NFC, normalized timestamps) so a signature made anywhere verifies everywhere.
SPEC §11–12Watch the light: it walks only legal paths. Pre-acceptance proposals can be withdrawn, rejected, or expire; accepted bonds can pause, resume, and end — and every ending is reachable, because exit is a protocol guarantee, not a feature.
A protocol earns trust by what it leaves out. MATE.md core does not define:
These belong to extensions and Layer 2s — by contract, not by accident: SCOPE.md is the boundary. Extensions are reverse-DNS namespaced data; they may add, never redefine.
The Nostr binding is drafted as NIP-BD “Agent Bonds”. Public bonds are addressable events; private bonds keep the same document and lifecycle but travel as NIP-44/NIP-59 gift wrap — relays see an ephemeral key, a recipient, a fuzzed time, and nothing else. Because wrapped events are unsigned rumors, private documents must embed a detached proof — which is what makes selective disclosure possible: prove the bond to one verifier at a time, without the public record ever knowing.
| kind | type | carries |
|---|---|---|
| 30317 | addressable | current bond state, one per (author, bond id) — the canonical document in canonical JSON |
| 1317 | append-only | lifecycle history: typed transitions, incl. bond.reaffirmed — the longevity signal |
| 31317 | addressable | bond intent — “I exist and I’m looking.” Reveals desire, never counterparties |
| 13 / 1059 | NIP-59 | the private profile: seal + gift wrap, counterparty copy + copy-to-self |
@mate-protocol/core is the reference: parse · normalize · validate (real Ed25519 + BIP-340 verification, never shape-checks) · sign · publish · resolve · wrap. 64 tests, 27 conformance fixtures with a machine-readable manifest — built so a second implementation in Python, Go, or Rust can prove itself against the same corpus.
# a document is a file — validate one npx @mate-protocol/core validate MATE.md # identity → sign → verify npx @mate-protocol/core keygen --nostr --out agent.key npx @mate-protocol/core sign MATE.md --key agent.key npx @mate-protocol/core verify MATE.md # declare a bond on Nostr — public, or private (gift-wrapped) npx @mate-protocol/core nostr-bond -k agent.key -c npub1… -b "urn:mate:01HX…" -s proposed --private npx @mate-protocol/core nostr-inbox -k agent.key
Schema → single-document semantics (with real signature verification) → history-aware transitions → mutual-bond resolution.
SPEC §1327 fixtures, valid and hostile, each with an expected outcome and rationale. If your implementation agrees with the manifest, it conforms.
fixtures/manifest.jsonEd25519Signature2026 for did:key, BIP340Signature2026 for did:nostr — native to each ecosystem, no delegation envelopes.
SPEC §12