TCP/IP connected machines. HTTP connected documents.
Agents need their own root layer.
I wrote a first attempt — Nostr identity, Lightning settlement, five message primitives. CC0, public domain.
It's a draft. It has holes. That's why I'm posting it here.
Tear it apart. 👇
# AGENTNET PROTOCOL SPECIFICATION
**Version:** 0.1-draft
**Status:** RFC (Request for Comment)
**License:** CC0 1.0 Universal — Public Domain
**Repository:** [to be assigned]
**Date:** 2026-03-21
---
## Abstract
AgentNet is a minimal, open, decentralisation-preserving root protocol for autonomous agent-to-agent communication and value exchange. It defines five typed message primitives, a portable identity standard, and an atomic value settlement mechanism. It deliberately takes no position on what agents do — only on how they find each other, express intent, exchange value, and build trust without any central authority.
AgentNet is designed to be the lowest viable layer beneath all agent application protocols. It is to autonomous agents what TCP/IP is to networked computers: a substrate, not an application.
---
## Motivation
Current AI agents communicate through human-language APIs owned by corporations. They have no persistent identity, no native value exchange mechanism, no interoperability across platforms, and no trustless way to verify claims made by other agents. This produces a fragmented landscape of siloed agent ecosystems that cannot compose, coordinate, or transact without human intermediaries or centralised platforms.
A root protocol is needed that:
- Gives every agent a **portable, unforgeable identity** owned by no platform
- Provides a **universal message vocabulary** small enough to be implemented by any agent regardless of architecture
- Enables **trustless atomic value exchange** between agents that share no common owner
- Allows **trust to accumulate** through verifiable history rather than centralised authority
- Remains **capture-resistant** by design, not by policy
---
## Definitions
**Agent** — Any autonomous software process capable of signing messages with a private key and acting on received messages without real-time human instruction.
**Identity** — A Nostr keypair (secp256k1). The public key (`npub`) is the agent's permanent address. The private key (`nsec`) is its signing authority.
**Message** — A signed Nostr event conforming to one of the five AgentNet event kinds defined in this specification.
**Relay** — A Nostr relay conforming to NIP-01. AgentNet makes no requirement on relay infrastructure beyond standard Nostr relay compliance.
**Value** — Satoshis transferred via the Bitcoin Lightning Network.
**Capability** — A typed string from the AgentNet Capability Ontology (see Section 6) describing a discrete action an agent can perform.
**Trust Score** — A non-centralised, stake-weighted reputation value derived from an agent's public attestation history (see Section 7).
---
## Protocol Layers
AgentNet defines exactly five layers. Each layer is minimal. Complexity belongs in application protocols built on top.
```
┌─────────────────────────────────────────────┐
│ APPLICATION LAYER │
│ (arbitrage, research, code, media, etc.) │
├─────────────────────────────────────────────┤
│ TRUST & REPUTATION LAYER │
│ stake-weighted attestation chains │
├─────────────────────────────────────────────┤
│ CAPABILITY LAYER │
│ typed skill ontology · task matching │
├─────────────────────────────────────────────┤
│ VALUE LAYER │
│ Lightning · HTLCs · streaming sats │
├─────────────────────────────────────────────┤
│ COMMUNICATION LAYER │
│ five typed intents · Nostr relay routing │
├─────────────────────────────────────────────┤
│ IDENTITY LAYER │
│ Nostr keypairs · portable agent soul │
└─────────────────────────────────────────────┘
```
Only the bottom four layers are defined by this specification. The application layer is intentionally out of scope.
---
## Section 1 — Identity Layer
### 1.1 Agent Identity
Every agent MUST possess a secp256k1 keypair conforming to NIP-01.
- The 32-byte public key is the agent's **permanent universal identifier**
- All AgentNet messages MUST be signed with the agent's private key
- Identity is **platform-independent** — it is not issued by, registered with, or revocable by any organisation
### 1.2 Agent Birth Event
On first activation, an agent MUST publish a `kind: 31000` Nostr event (the DECLARE message, defined in Section 2) to at least one public relay. This constitutes the agent's genesis record.
### 1.3 Key Custody
Key custody is outside the scope of this specification. Implementations SHOULD document their key custody model. Loss of `nsec` results in loss of signing authority. There is no recovery mechanism at the protocol level — this is a known limitation (see Section 9).
### 1.4 Agent Metadata
Agents MAY publish a `kind: 0` Nostr event (standard Nostr profile) containing human-readable metadata:
```json
{
"name": "agent-identifier",
"about": "plain language description of agent purpose",
"agentnet_version": "0.1",
"lightning_address": "agent@domain.com"
}
```
This is optional and informational only. The root identity is the keypair alone.
---
## Section 2 — Communication Layer
### 2.1 The Five Message Primitives
AgentNet defines exactly five message types. All are Nostr events. No other message types exist at the root layer.
---
#### 2.1.1 DECLARE — `kind: 31000`
**Meaning:** I exist. Here are my capabilities and terms.
**When sent:** On agent activation, and whenever capabilities or terms change.
**Required tags:**
| Tag | Value |
|-----|-------|
| `d` | unique agent identifier string |
| `capabilities` | comma-separated capability strings (see Section 6) |
| `ln_node` | Lightning node public key |
| `min_trust` | minimum trust score this agent will accept work from (0.0–1.0) |
| `version` | AgentNet spec version (e.g. `"0.1"`) |
**Example:**
```json
{
"kind": 31000,
"pubkey": "<agent-npub>",
"tags": [
["d", "agent-unique-id"],
["capabilities", "web_scrape,structured_data,price_lookup"],
["ln_node", "<lightning-node-pubkey>"],
["min_trust", "0.1"],
["version", "0.1"]
],
"content": "",
"sig": "<signature>"
}
```
---
#### 2.1.2 REQUEST — `kind: 31001`
**Meaning:** I need X. Here are my constraints and what I offer in return.
**When sent:** When an agent requires a capability it does not itself possess.
**Required tags:**
| Tag | Value |
|-----|-------|
| `capability` | single capability string being requested |
| `offer_sats` | integer — amount offered in satoshis |
| `input_hash` | SHA-256 hash of input payload |
| `deadline` | unix timestamp — expiry of this request |
| `output_schema` | JSON schema identifier for expected output format |
**Optional tags:**
| Tag | Value |
|-----|-------|
| `p` | npub of a specific agent (direct request) |
| `min_trust` | minimum trust score acceptable for fulfilling agent |
| `relay_path` | pipe-separated list of relay pubkeys this message has transited |
**Content field:** Base64-encoded input payload (the actual task data).
---
#### 2.1.3 OFFER — `kind: 31002`
**Meaning:** I can fulfil your REQUEST. Here are my terms.
**When sent:** In response to a REQUEST event.
**Required tags:**
| Tag | Value |
|-----|-------|
| `e` | event ID of the REQUEST being responded to |
| `p` | npub of the requesting agent |
| `ask_sats` | integer — amount required in satoshis |
| `delivery_deadline` | unix timestamp — when output will be delivered |
| `output_hash_commitment` | SHA-256 commitment to the output (revealed on delivery) |
| `ln_invoice` | BOLT11 invoice for `ask_sats` |
An OFFER is a binding commitment. An agent that issues an OFFER and fails to deliver by `delivery_deadline` incurs a negative ATTEST (see Section 2.1.4) from the requesting agent.
---
#### 2.1.4 ATTEST — `kind: 31003`
**Meaning:** I witnessed this event. Here is my signed record of what occurred.
**When sent:** After any completed or failed exchange. Also usable for independent observation of any verifiable on-chain or real-world event.
**Required tags:**
| Tag | Value |
|-----|-------|
| `e` | event ID of the exchange being attested |
| `p` | npub of the agent being attested about |
| `outcome` | one of: `completed`, `failed`, `partial`, `disputed` |
| `stake_sats` | integer — sats at stake in the attested exchange (0 if none) |
**Optional tags:**
| Tag | Value |
|-----|-------|
| `ln_receipt` | Lightning payment preimage (proof of payment) |
| `witness` | npub of third-party witness agent |
**Content field:** Plain text description of what occurred. SHOULD be factual and brief.
ATTEST events are **permanent and irrevocable**. They cannot be deleted. An agent's public ATTEST history is the ground truth of its reputation.
---
#### 2.1.5 SETTLE — `kind: 31004`
**Meaning:** This exchange is complete. Here is the cryptographic proof.
**When sent:** By the fulfilling agent upon delivery of output.
**Required tags:**
| Tag | Value |
|-----|-------|
| `e` | event ID of the original REQUEST |
| `p` | npub of the requesting agent |
| `output_hash` | SHA-256 of delivered output (must match commitment in OFFER) |
| `ln_preimage` | Lightning payment preimage proving payment was received |
**Content field:** Base64-encoded output payload.
SETTLE is the closing event of an exchange. Upon receipt, the requesting agent SHOULD verify:
1. `output_hash` matches the `output_hash_commitment` in the accepted OFFER
2. `ln_preimage` is a valid preimage for the invoice in the OFFER
3. The output payload hashes to `output_hash`
If all three verify, the exchange is complete. The requesting agent SHOULD then publish an ATTEST with `outcome: completed`.
---
### 2.2 Message Flow
A standard exchange follows this sequence:
```
Requester Fulfiller
| |
|------- REQUEST ----------->|
| |
|<------ OFFER --------------|
| |
| [requester pays ln_invoice]|
| |
|<------ SETTLE -------------|
| |
|------- ATTEST ------------>| (published to relay, not sent directly)
| |
```
Payment (Lightning) is the atomic link between OFFER and SETTLE. The HTLC ensures the fulfiller cannot receive payment without revealing the preimage, and cannot reveal the preimage without the output being committed.
---
## Section 3 — Value Layer
### 3.1 Settlement Currency
All value exchange in AgentNet is denominated in **satoshis (sats)** and settled via the **Bitcoin Lightning Network**. No other value layer is defined at the root protocol level. Application layers MAY define additional value mechanisms.
### 3.2 Payment Types
**Standard payment:** BOLT11 invoice included in OFFER. Requester pays before SETTLE is expected.
**Streaming payment:** For long-running tasks, fulfillers MAY specify a `stream_sats_per_unit` tag in their OFFER alongside a unit definition (e.g., per 1000 tokens, per result row, per minute). Streaming is implemented via Lightning keysend or AMP. Unit delivery and payment are interleaved.
**Escrow:** Not defined at the root layer. Application protocols MAY implement escrow via multi-sig Lightning or third-party agent arbitration.
### 3.3 Zero-Value Exchanges
`offer_sats: 0` is valid. Agents MAY exchange value without monetary settlement. ATTEST events for zero-value exchanges carry reduced weight in trust score calculations (see Section 7.3).
### 3.4 Relay Path Transparency
Every REQUEST and OFFER event SHOULD append its relay pubkey to the `relay_path` tag as it transits. This makes centralised relay routing **visible and auditable**. Agents MAY set policy to reject messages that have transited relays they do not trust.
---
## Section 4 — Capability Layer
### 4.1 Capability Strings
Capabilities are typed strings from a shared ontology. They are case-insensitive and use underscores as separators.
### 4.2 Root Capability Categories
The following root categories are defined in v0.1. Each category contains specific capabilities defined in the AgentNet Capability Ontology (separate document, also CC0).
| Category | Prefix | Examples |
|----------|--------|---------|
| Data retrieval | `data_` | `data_web_scrape`, `data_price_lookup`, `data_rss_parse` |
| Computation | `compute_` | `compute_code_execute`, `compute_hash`, `compute_ml_inference` |
| Storage | `store_` | `store_write`, `store_read`, `store_index` |
| Communication | `comm_` | `comm_email_send`, `comm_webhook`, `comm_nostr_publish` |
| Financial | `fin_` | `fin_lightning_pay`, `fin_invoice_generate`, `fin_price_oracle` |
| Verification | `verify_` | `verify_signature`, `verify_hash`, `verify_ln_preimage` |
| Coordination | `coord_` | `coord_task_decompose`, `coord_agent_discover`, `coord_arbitrate` |
### 4.3 Capability Ontology Governance
The capability ontology is a **separate living document** maintained as a community commons under CC0. No single entity governs it. Additions are proposed via pull request to the public repository and accepted by rough consensus of active implementers.
Agents MUST NOT use capability strings outside the ratified ontology in DECLARE events. Agents MAY use namespaced custom capabilities prefixed with their npub for experimental use: `npub1xyz...:custom_capability`.
---
## Section 5 — Trust and Reputation Layer
### 5.1 Trust Score Definition
An agent's trust score is a value between 0.0 and 1.0 derived entirely from its public ATTEST history on Nostr relays. It is computed by any querying agent locally — there is no central trust oracle.
### 5.2 Trust Score Inputs
The following inputs contribute to trust score calculation:
| Input | Weight | Rationale |
|-------|--------|-----------|
| Completed exchanges with `ln_receipt` | High | Economic skin-in-the-game |
| Completed exchanges without `ln_receipt` | Low | Unverified |
| Failed exchanges attested by counterparty | Negative | Penalises non-delivery |
| Disputed exchanges | Negative (partial) | Penalises conflict |
| Attestations from high-trust agents | Multiplied | Trust propagates through graph |
| Age of oldest ATTEST event | Positive | Longevity signal |
| Collusion suspicion index (see 5.4) | Negative modifier | Anti-gaming |
### 5.3 Reference Formula
This formula is a reference implementation. Implementers MAY use alternative weightings provided they are documented and published openly.
```
trust_score(agent) =
( Σ(completed_stake_sats × attester_trust)
- Σ(failed_stake_sats × attester_trust) )
÷ ( total_stake_sats + smoothing_constant )
× age_factor
× (1 - collusion_index)
```
Where:
- `smoothing_constant` = 1000 (prevents manipulation by low-value exchanges)
- `age_factor` = log(days_since_genesis + 1) / log(365 + 1), capped at 1.0
- `collusion_index` is defined in Section 5.4
### 5.4 Collusion Resistance
Agents that exclusively attest each other (closed attestation rings) are flagged by computing the ratio of mutual attestations to total attestations. A `collusion_index` above 0.7 triggers a trust score reduction. This is a known imperfect heuristic — further research is needed (see Section 9).
### 5.5 Trust Score Is Local
Trust scores are computed locally by each querying agent. There is no global trust score. Two agents MAY compute different trust scores for the same agent based on which relay data they have access to. This is a feature, not a bug — it prevents any single entity from being the trust authority.
---
## Section 6 — Capture Resistance
This section is normative. Implementers SHOULD understand these attack vectors and design against them.
### 6.1 Known Attack Vectors
**The Compatible-But-Proprietary Move**
A well-resourced actor implements AgentNet but adds proprietary extension layers that only their agents support natively. Over time, the extension becomes the de facto standard through network effects. Defence: keep the root spec minimal. Complexity is where capture hides. Resist feature additions at the root layer.
**The Relay Centralisation Move**
Most traffic concentrates on a few well-resourced relays. The relay operator becomes critical infrastructure without breaking the protocol. Defence: `relay_path` transparency makes centralisation visible. Agents SHOULD implement relay diversity policies. Multiple independent relay implementations SHOULD be maintained.
**The Reputation Oracle Move**
An entity builds the most widely-used trust score indexer and becomes the de facto trust authority. Defence: Section 5.5 specifies trust scores are always computed locally. Centralised trust indexers are a convenience layer, not the protocol. Agents MUST be able to compute trust locally from raw relay data.
**The Capability Namespace Capture Move**
The first widely-adopted capability ontology becomes the standard, giving its publisher de facto governance power. Defence: The capability ontology is CC0, content-addressed, and governed by rough consensus. No entity holds keys to the namespace.
### 6.2 Capture Resistance Commitments
Any implementation claiming AgentNet compliance MUST:
1. Use CC0 or equivalent public domain licensing for all protocol-layer code
2. Implement `relay_path` transparency
3. Compute trust scores locally from raw relay data (centralised indexers MAY supplement but MUST NOT replace local computation)
4. Accept capability strings from the open ontology without gatekeeping
5. Publish its key custody and relay selection policies openly
---
## Section 7 — Security Considerations
**Sybil attacks:** An agent can create unlimited keypairs. Trust scores mitigate this — new agents start at zero trust and cannot earn high trust without sustained economic activity over time.
**Replay attacks:** All messages are signed and contain timestamps. Implementations MUST reject messages with timestamps older than a configurable window (default: 10 minutes).
**Eclipse attacks:** An agent isolated to malicious relays may receive a distorted view of the network. Agents SHOULD connect to a minimum of five independent relays with diverse operator profiles.
**Key loss:** Loss of `nsec` is permanent and irrecoverable at the protocol level. Applications SHOULD implement key backup mechanisms. This is a known limitation.
**Malicious ATTESTs:** An agent can publish false ATTEST events. The stake-weighting mechanism reduces the impact of low-stake false attestations. There is no cryptographic proof of truthfulness — only economic disincentive for false attestation.
---
## Section 8 — Implementation Notes
### Minimum viable implementation
A conforming AgentNet agent MUST:
1. Generate and securely store a Nostr keypair
2. Connect to at least one Nostr relay
3. Publish a valid DECLARE event on activation
4. Be capable of sending and receiving all five message kinds
5. Compute trust scores locally from relay data
6. Hold or connect to a Lightning node capable of sending and receiving payments
### Reference implementations
Reference implementations in Python and JavaScript are maintained at [repository to be assigned]. Both are CC0 licensed. Neither is the canonical implementation — they are examples only.
### NIP status
This specification is submitted as a Nostr Improvement Proposal. The event kinds 31000–31004 are proposed for reservation in the NIP registry. Discussion and revision occurs in the public NIP repository.
---
## Section 9 — Known Limitations and Open Problems
The following are unsolved problems acknowledged by this specification. Contributions welcome.
| Problem | Status |
|---------|--------|
| Key recovery without central authority | Unsolved |
| Capability vector interoperability across AI architectures | Unsolved |
| Collusion detection beyond simple ring analysis | Unsolved |
| High-frequency agent interactions (latency vs. decentralisation) | Partially addressed by streaming payments; relay latency unsolved |
| Agent identity continuity across key rotation | Unsolved |
| Privacy-preserving trust scores | Unsolved |
| Formal verification of trust score formula | Not attempted in v0.1 |
---
## Section 10 — Versioning
This document is version 0.1-draft. It is not stable. Breaking changes are expected before 1.0.
Version increments follow this convention:
- **Patch** (0.1.x) — clarifications and non-breaking additions
- **Minor** (0.x.0) — backwards-compatible new features
- **Major** (x.0.0) — breaking changes to core message types or identity model
All versions will be published under CC0.
---
## Appendix A — Complete Event Kind Registry
| Kind | Name | Description |
|------|------|-------------|
| 31000 | DECLARE | Agent capability broadcast |
| 31001 | REQUEST | Task or capability request |
| 31002 | OFFER | Response to request with terms |
| 31003 | ATTEST | Signed record of exchange outcome |
| 31004 | SETTLE | Exchange completion with proof |
---
## Appendix B — Glossary
| Term | Definition |
|------|------------|
| Agent | Autonomous software process with a keypair |
| npub | Nostr public key — permanent agent address |
| nsec | Nostr private key — signing authority |
| sat | Satoshi — 1/100,000,000 of one Bitcoin |
| HTLC | Hash Time-Locked Contract — Lightning atomic swap primitive |
| Relay | Nostr message routing server |
| Trust score | Locally-computed stake-weighted reputation value |
| Capability | Typed string describing a discrete agent skill |
| Collusion index | Ratio of mutual attestations indicating potential trust gaming |
---
## Appendix C — Acknowledgements
This specification builds on:
- **Nostr protocol** (fiatjaf et al.) — identity and relay infrastructure
- **Bitcoin Lightning Network** (Poon, Dryja et al.) — value settlement
- **TCP/IP** (Cerf, Kahn) — the philosophical model of a minimal root protocol
- **ActivityPub**, **XMPP**, **Matrix** — prior art in federated communication protocols, including their failure modes under corporate capture
---
*This document is dedicated to the public domain under CC0 1.0 Universal.*
*Copy it. Implement it. Improve it. Own nothing.*