Fleetmesh fleetmesh

The fleetmesh Protocol · part 4 of 10

Replication

Gossip synchronization, event filtering rules, and integration with existing relay tooling.

Replication

Replication Boundaries & Synchronization Rules

Nostr events are immutable and self-authenticating, so replication is set union over a grow-only set, with deletions and replaceable-supersession as the two exceptions. There is no ordering guarantee beyond created_at, no consensus, and no notion of a primary. Two nodes that have exchanged every event in a shard hold identical sets; two that have not are both correct and simply behind.

Interest contracts

A peer does not receive a firehose. It declares an interest — a filter, a time range and a direction — and the grant is scoped to it. Pushing an event outside the interest is an S3 finding, not merely inefficient: it is the mechanism by which a misbehaving peer would try to make its traffic someone else's problem.

  • pull — the peer fetches; the issuer serves within budget.
  • push — the peer sends; every event MUST match the interest filter.
  • both — symmetric, and the common case between anchors.

Reconciliation uses NIP-77 negentropy. A node MUST support NIP-77 to peer. Range synchronization is an essential protocol prerequisite. The legacy alternative—re-broadcasting timestamp windows and discarding duplicates—wastes bandwidth and renders duplicate-ratio reputation metrics ineffective.

Pluggable Storage & Deterministic Range Fingerprints (MeshStore)

To allow existing relays (e.g. strfry, khatru, nostr-rs-relay) to join the mesh without changing their underlying database engine, all event storage, retrieval, and range indexing is abstracted behind the async MeshStore trait.

crates/mesh — Storage & Range Fingerprint Trait

#[async_trait]
pub trait MeshStore: Send + Sync + 'static {
    /// Retrieve an event by its 32-byte identifier
    async fn get_event(&self, id: &[u8; 32]) -> Result<Option<Event>, StorageError>;

    /// Insert an independently authenticated event into local storage
    async fn insert_event(&self, event: &Event, now: u64) -> Result<InsertStatus, StorageError>;

    /// Check presence of an event without decoding its payload
    async fn has_event(&self, id: &[u8; 32]) -> Result<bool, StorageError>;

    /// Calculate a deterministic NIP-77 range fingerprint over (filter, since, until)
    async fn fingerprint_range(&self, filter: &Filter, since: u64, until: u64, now: u64)
        -> Result<[u8; 16], StorageError>;

    /// Enumerate all event IDs matching a filter within a timestamp interval
    async fn enumerate_range(&self, filter: &Filter, since: u64, until: u64, now: u64)
        -> Result<Vec<[u8; 32]>, StorageError>;
}

Deterministic range fingerprinting. The fingerprint is NIP-77's, not a second one. fleetmesh defines no fingerprint of its own, because a node that speaks NIP-77 already computes this and a second construction over the same data is one more thing for two implementations to disagree about.

range fingerprint — NIP-77 Negentropy V1, restated for completeness

acc  := Σ (id as 32-byte little-endian uint) mod 2256
fp   := SHA256(acc as 32 bytes little-endian || varint(count))[0..16]

varint is base-128, most significant digit first, high bit set on all
but the last byte. 16 bytes on the wire, and the count is what stops the
additive structure colliding on cardinality alone.

It is a sum, and that is the point. Set reconciliation works by splitting a range and comparing halves. Because addition composes, the fingerprint of a range is the sum of its sub-ranges: a split is an index lookup, and a node can maintain running sums rather than re-reading events. An order-dependent chained hash would force a re-hash of every element in every new sub-range at every level of the split, which is the wrong shape for the protocol this document already requires. It also makes the fingerprint order-independent, so no sort rule is needed to compute it — sorting by (created_at ASC, id ASC) remains required for enumerate_range, whose output order is observable.

Which events are in the set. Pinning the algorithm is only half of agreement; the other half is membership, and two backends can each compute NIP-77 correctly over different sets and never converge. Four rules decide it, and each is a place where a locally reasonable choice silently breaks reconciliation. They are normative and live in constants.json under store.

  • Ephemeral kinds are never stored (20000 ≤ n < 30000), so they never enter a fingerprint.
  • Replaceable and addressable kinds keep only the winner — later created_at, and on a tie the lexicographically lower id. Retaining a superseded version is not a local choice, because it changes the fingerprint.
  • A NIP-09 deletion removes only events its own author signed, and removes them permanently: the id is tombstoned so a later re-offer cannot resurrect it. The kind 5 is itself stored and replicates, because a peer that never receives it never learns of the deletion. A deletion that arrives before its target still binds, so a tombstone records which key asked — the authority check needs the target's author, and that is not known yet. Checking it on arrival instead is what makes the outcome independent of the order the two events turned up in.
  • An expired event is not in the set. Two peers evaluating either side of that instant disagree for as long as their clocks differ, bounded by the same 60 second skew allowance the accounting uses. This is why the range methods take now.

The since and until arguments bound the time axis, and a filter's own since/until narrows further: the intersection, so that neither can silently widen the other.

Every storage backend — LMDB, SQLite, PostgreSQL, flat files — MUST produce byte-identical fingerprints for identical event sets. How it does so is deliberately unspecified: a prefix-sum index, a segment tree over the timestamp axis, or a naive scan are all conformant, because only the value on the wire is normative. An implementation is free to make range splits O(1) and most should.

Measured

What reconciliation costs depends on how the differences are distributed, not only on how many there are. § Why join claims a node offline for a week catches up in kilobytes of fingerprints. Against 10,000 events that holds, and the reason it holds is that being offline produces a contiguous gap:

DifferenceRound tripsBytesAgainst 32 bytes per id
none — the sets match1337—
3, scattered22,81929×
500, contiguous and recent217,1531.1×
500, scattered through the history2142,3028.9×

The last row is the honest caveat. When differences are spread thinly through the whole range almost every sub-range differs, the split degenerates towards exchanging the ids themselves, and reconciliation costs several times what sending the ids would have. That is a property of range-based reconciliation rather than of this implementation: varying the split arity between 8 and 32 moves the figure by under ten percent while trading bytes against round trips. A node catching up after downtime is in the third row. A node whose peer has been quietly withholding scattered events is in the fourth, and the withholding case in § Attack surface should be read with that cost in mind.

Executable

ref/negentropy.py implements NIP-77 V1 over this store — the message encoding, the bound rules, and reconciliation for both sides — and core/tests/test_negentropy.py is where the figures above come from. It has not been run against hoytech's reference implementation, because there is no binary here to run it against; what is checked is that the encoder round-trips, that it reproduces the frames pinned in vectors/negentropy.json, and that sixty seeded random set pairs converge on exactly the right difference.

ref/store.py implements this against two backends, an in-memory map and SQLite, and core/tests/test_store.py is the shared suite the § Conformance section requires: the same assertions run against each, then both fed one history in a hundred shuffled orders and required to produce one fingerprint. vectors/store.json pins the corpus, the enumeration and eight range fingerprints, so a third backend can check itself without running any of this.

The delivery envelope

Events crossing between nodes are wrapped, and the wrapper is where accountability lives. Every node that forwards an event appends its signature over (event_id, prev_hop, at). A receiver therefore knows not just who handed it the event but the whole chain back to the node that first put it into federation, and when each of them passed it on. at is inside the signature because a field a signature does not cover is a field anyone may rewrite: without it a hop could be lifted onto another moment, and a path proved that a node forwarded an event but never when. It is also the only thing a forwarder signs for an event it did not write, which is what lets an envelope stand as evidence against the forwarder.

A sync/1.0/deliver carries its events in these envelopes and nowhere else, one per event, and its body is the count. A receiver MUST refuse a deliver that carries no delivery-envelope attachment, and MUST NOT store an event no verifying envelope covers. The rule is not tidiness. An event accepted without provenance is an event whose delivery can never be reported: a report may cite an envelope, or an event the peer itself authored, and a third party's event with no envelope is neither, so omitting the attachment would be a free way to commit the interest offence unpunishably. Carrying the events in the body as well, which an earlier draft did, cost twice the bytes for one copy nobody read — and those bytes are metered against the receiver's own grant.

delivery envelope — sync/1.0/deliver attachment

{
  "event": { … the nostr event, unmodified and independently verifiable … },
  "path": [
    { "node": "did:nostr:<origin>",  "at": 1787000001, "sig": "…" },
    { "node": "did:nostr:<relayer>", "at": 1787000004, "sig": "…" }
  ],
  "grant": "<event id of the grant this delivery is charged against>",
  "window": 496389
}

what a hop signs — delivery.hop_signature in constants.json

msg := SHA256("fleetmesh/hop/1" || "|" || event_id || "|" || prev_hop || "|" || at)
sig := BIP-340(node_key, msg)

event_id   the wrapped event's id, 64 lowercase hex
prev_hop   the previous path entry's node string, exactly as written; empty for the first hop
at         this hop's own unix seconds, in decimal

The domain label keeps a hop signature from being mistaken for a nostr event id or for anything else the same key signs. A path longer than max_forward_hops (three) is rejected, and a peer that keeps sending them is committing the hop-limit S3 the ladder already names. vectors/envelope.json pins a two-hop path under deterministic keys, so an implementation can check its messages and signatures byte for byte.

Transitive accountability

This prevents grant-evasion routing (e.g. node B relaying traffic through node C to bypass node A's budget limits). Routing accountability is explicit: operators are directly responsible for originated traffic and forwarded transit.

Deletions and supersession

  • NIP-09 deletion authority. Stores MUST verify that NIP-09 deletions target events authored by the deletion signer. This ownership check ensures safety: a hostile peer's Kind 5 deletion cannot alter another author's data, regardless of forwarding path.
  • Replaceable and addressable supersession is resolved by created_at, then by lexicographically lower event id, exactly as NIP-01 specifies. Peers MAY exchange only the winner.
  • NIP-40 expirations are honoured on receipt. A node MUST NOT accept an already-expired event from a peer, and a peer that sends them in bulk is backfilling garbage — S1.
  • A deletion is a request, not an erasure guarantee. This document does not pretend otherwise, and neither should any interface built on it.

Blobs

Blossom BUD-04 (PUT /mirror) provides HTTP fallback. Servers MUST verify the authorization event's x tag against the computed SHA-256 hash of the received payload. Nodes MUST NOT credit unverified blobs toward coverage claims. Nodes SHOULD reject blobs lacking associated local events to prevent unauthorized CDN exploitation.

Never replicated

The full list is in § Two networks, because most of it is a boundary rule for operators bridging an existing estate. Two entries are protocol-level, and every node enforces them against every peer whether or not any other service is anywhere nearby:

  • Kind 24133 — NIP-46 signer traffic. Ephemeral, and federating it would let any node observe every pairing and every signing event of every bunker in reach. MUST NOT cross, on any transport, under any grant.
  • Kind 1059 — gift wraps replicate only to nodes named in the recipient's own kind 10050 DM relay list, a check any node can perform from public data. Never in bulk, and never on a filter a third party supplied.

Symmetrical Ingress & Egress Policy Seams (pluginIn / pluginOut)

An operator has as much reason to govern what leaves their relay as what arrives. In addition to NIP-77 interest filters, fleetmesh specifies symmetrical policy seams on both ingress and egress paths. These seams allow external policy engines or plugins (compatible with strfry write-policy and nostr-router) to evaluate, filter, and redact traffic dynamically.

Direction Hook / Seam Trigger & Payload Context Permitted Actions
Ingress pluginIn / write-policy Fires when an inbound event arrives over a peering or delivery envelope before committing to local store: {"action": "ingress", "event": {...}, "source": {"did": "did:nostr:...", "tier": "member"}} {"action": "accept"}
{"action": "reject", "msg": "..."}
{"action": "shadowReject"}
Egress pluginOut / egress-policy Fires before an event is emitted to a peer via negentropy range sync, live subscription, or sync/1.0/deliver: {"action": "egress", "event": {...}, "target": {"did": "did:nostr:...", "tier": "member", "class": "edge"}} {"action": "allow"}
{"action": "drop", "msg": "..."}
{"action": "shadowDrop"}
{"action": "redact", "fields": ["tags"]}
Why egress policy matters

Egress policy enforces local shard sovereignty. Operators prevent internal notes or quarantined events from leaking to wide-mesh peers, enforce tier-based media rules, and execute compliance filters before data leaves the local perimeter.

Prior art

Integration with Existing Relay Tooling

Relay synchronization has established production tools, notably strfry router. Any new specification must clearly state its relationship to existing tools. The comparison begins with a straightforward distinction: router is deployed and operational at scale; fleetmesh is a formal specification.

The core distinction is structural. strfry router is a replication tool; fleetmesh is a peering protocol. Router coordinates event transfer between pre-trusted relays. Fleetmesh establishes bilateral relationships, dynamic capacity allocation, and mutual accountability between untrusted peers. The two designs address different operational requirements.

How router works

One process, acting as a nostr client to many relays, driven by a config file of named streams. Each stream has a direction — up, down or both — a list of relay URLs, an optional nostr filter, and optional plugins consulted before storing or before transmitting. Edit the file and it reloads, computing the minimally invasive change rather than restarting. A relay that cannot be reached is retried forever.

strfry routerfleetmesh
peer identitya URL you typeda key, resolvable as did:nostr
relationshipone-sided config; the far end never agreednegotiated, expressed as two grants
directionup / down / bothpush / pull / both — near-identical, arrived at separately
selectiona nostr filter per streaman interest filter, scoped by the grant
reconciliationlive REQ with an implicit limit:0NIP-77 negentropy, required to peer at all
abuse controlplugins the operator writespublished budgets, signed receipts, a fixed ladder
discoverynone, by designgossipsub, relays and descriptors
forwarded trafficinvisible to the far endsigned hop path, charged to every node in it
operator surfaceone legible config filegrants, tiers, receipts, retention modes

Where router is simply better

Four of these are gaps in this document rather than differences of philosophy. They are listed because a comparison that only flattered the author would be worth nothing.

use router, not this
Between relays a single operator controls, fleetmesh is overkill and router is the correct tool. The reputation machinery earns its keep only when peers are strangers; between your own machines it is pure cost with no counterparty risk to price. An operator running a two-region cluster should reach for router and ignore this document.
legibility (incorporated via meshctl)
Simple parameters (dir, urls, filter) allow operators to configure streams in seconds. Fleetmesh incorporates this directly via the declarative meshctl manifest suite (apiVersion: fleetmesh.org/v1alpha1). Operators declare node identity, peerings, and filter scopes in clean, human-readable YAML or JSON.
symmetrical egress policy (incorporated via pluginOut)
Router consults a plugin on the way out as well as on the way in (pluginUp and pluginDown). fleetmesh incorporates this directly via symmetrical pluginIn (write-policy) and pluginOut (egress-policy) seams, giving operators granular, dynamic control over outbound data emission and local shard sovereignty.
hot reconfiguration (incorporated via meshctl apply)
Router computes configuration deltas without connection drops. Fleetmesh adopts this directly: meshctl apply calculates live state diffs and dynamically updates NIP-77 subscription ranges. Active TLS and QUIC sessions remain connected during filter updates.

Where fleetmesh answers something router leaves open

Router's documentation notes that bidirectional streams echo events back to source relays, which then reject them as duplicates. Fleetmesh's dup_ratio limit and envelope origin tracking address this condition directly. Accounting for duplicate ratios provides empirical feedback on network topology efficiency.

The second distinction is explicit bilateral consent. A traditional router stream configured with dir = "up" transmits events to a relay that never signed an agreement to accept them. In practice, operators configure streams only between allied relays. However, the legacy protocol provides no mechanism to record this bilateral relationship. Fleetmesh makes bilateral consent a first-class protocol primitive: a grant is a signed, auditable, and reciprocally enforced contract.

They compose today, with no work at all

A fleetmesh node is a NIP-01 relay, so strfry router can stream to and from one right now with zero fleetmesh support on either side. A fleetmesh sync component, conversely, looks to strfry like an ordinary client. There is no migration and no bridge to build. An operator can run router against fleetmesh nodes, adopt grants for the peerings where counterparty risk is real, and leave router doing the rest.

A debt worth stating

Negentropy came out of this project. It is the set-reconciliation protocol NIP-77 standardises, and § Replication makes it a hard prerequisite for peering. fleetmesh's reconciliation layer is not an alternative to that work; it is that work, depended upon.

Quantum Relay (quantum-rely), and continuous-time propagation

Built on the Go rely v2 framework and packaged for self-hosting via quantumrelay_ynh, Quantum Relay uses continuous-time quantum walks over graph Laplacians. It calculates note propagation probabilities to prioritize fetching from neighboring relays, combined with diffusive consensus and exponential reputation damping.

Like router, Quantum Relay is a concrete, working implementation with rigorous benchmark suites (Jacobi eigendecomposition for N ≤ 128 nodes, sparse Taylor approximations for larger graphs) and automated multi-node stress tests. The comparison clarifies how a physics-inspired routing engine contrasts with an accountable, contract-driven peering standard.

Quantum Relay (quantum-rely)fleetmesh
propagation triggerquantum walk probability amplitude: |⟨i|exp(−iLt)|s⟩|² > θNIP-77 negentropy range reconciliation over grant filters
propagation pathwave interference across Laplacian; multi-hop phase resonancehierarchical fingerprint bisection over scoped interest sets
consensus modeldiffusive gossip delta averaging toward global round convergencestrictly subjective local views; no global state or shared rounds
reputation & spamcontinuous exponential damping: exp(−2γ|rep|t) + Kind 19845-tier ordinal ladder (S0–S4) + evidence-backed Kind 30802 reports
rate enforcementinternal per-client & per-peer token bucketsbilateral published budgets (Kind 30801) + signed receipt hash chains
node classeshomogeneous server-to-server (public ports 443 + 8443)3-tier heterogeneous mesh: Anchor (VPS), Edge (NAT), Leaf (Mobile)
wire & transportNostr WebSockets (wss://) on TLS peer mesh portiroh (QUIC/hole-punching), libp2p gossipsub, HTTPS, Kind 21059/1059
peer identityrelay URL + TLS certificate + NIP-42 pubkeysW3C DID (did:nostr) with multikey binding
extended servicesevent storage (SQLite/memory) + WebSocket relaydecentralized WASM compute market (Kind 30810/30811) with Lightning

Where Quantum Relay is simply better

implemented and benchmarked
cmd/quantum-relay is a production-grade Go binary with end-to-end integration tests, high-concurrency websocket pipelines, and an automated YunoHost packaging suite. fleetmesh is currently a specification draft; Quantum Relay is running code you can deploy to a server today.
propagation in non-uniform topologies
Quantum walk amplitudes superimpose across every graph path at once. Notes therefore cross non-uniform, sparse or hierarchical relay graphs by constructive interference, with no explicit routing table. Direct 1-hop hubs can be bypassed organically if a 2-hop sibling path achieves phase resonance earlier.
zero wire overhead on standard clients
Quantum Relay operates entirely within the native Nostr vocabulary (REQ, EVENT, EOSE, NIP-11, NIP-42) and lightweight JSON envelopes. Clients and peer relays do not need to speak DIDComm v2, verify multikey knots, or unpack custom envelope encodings to exchange notes.

Where fleetmesh answers something Quantum Relay leaves open

the mobile & NAT boundary (a phone is a node)
Quantum Relay requires two open, public-facing TCP ports with TLS termination (443 for clients, 8443 for the peer mesh), restricting participation to servers with public IPs. fleetmesh's transport architecture (Iroh QUIC with native hole punching and libp2p) treats NAT-traversed home servers (Edge) and mobile phones (Leaf) as first-class mesh nodes with their own cryptographic identity and local storage.
verifiable evidence over arithmetic averaging
fleetmesh rejects arithmetic reputation averaging. Adverse reports (Kind 30802) require subject-signed cryptographic evidence (such as receipt heads or out-of-scope events). Third-party hearsay can only lower standing within an operator's local subjective trust horizon (θ = 1.0).
auditable bilateral commitments
In Quantum Relay, rate limits are private token buckets enforced unilaterally inside each relay process. fleetmesh's published grants (Kind 30801) and receipt hash chains turn rate enforcement into a mutual, verifiable contract where silence or misreporting (S2) is penalized more severely than an honest traffic overrun (S1).
Composition across layers

The two designs operate at complementary levels. An Anchor-class fleetmesh node can use graph Laplacians and quantum-walk propagators as internal scheduling heuristics. This prioritizes active peer grants for NIP-77 reconciliation and minimizes redundant synchronization bandwidth across dense sub-meshes.

Ecosystem Bridges

Ecosystem Standards & Interoperability Bridges

A protocol that builds custom silos where proven open standards exist wastes engineering effort and fractures the network. fleetmesh follows a strict rule: offload whatever a merged, standardised Nostr NIP already does. Then bridge in both directions, so ordinary clients and relays gain mesh capabilities without running fleetmesh code.

Standardized Primitives Reused Directly

NIP / StandardRole in fleetmeshWhy Custom Design Was Avoided
NIP-77 (Negentropy) Event replication & range reconciliation Negentropy solves fingerprint tree bisection with optimal byte efficiency. Reused directly across Iroh QUIC streams and WebSocket fallbacks.
NIP-B7 / NIP-94 (Blossom) Binary package & bytecode distribution Content-addressed blob storage with SHA-256 digests. Distributes .npk packages and WASM compute modules without custom storage daemons.
NIP-56 (Reporting Kind 1984) User content moderation ingress Standardized user-reported spam/abuse. Feeds local ingress filters and author grant evaluations.
NIP-44 / NIP-59 Ciphertext & gift-wrapped control envelopes Versioned ChaCha20 with HMAC-SHA256 (encrypt-then-MAC) used for Kind 30801 grant envelopes and store-and-forward control messaging.
NIP-67 EOSE completeness hints Projected from Kind 30803 coverage claims to notify querying clients whether historical shard ranges are complete.

Bidirectional Ecosystem Bridges

Bridge 1: NIP-66 Relay Discovery (Kind 30166)
A node with a public face MAY publish a standard NIP-66 kind 30166 about it, one per ws or wss endpoint its kind 11801 declares, so that relay lists and explorers that know nothing about fleetmesh find it the way they find any relay. The event says what the face is and what it accepts, read from things the node already publishes or serves: d is the endpoint in the canonical form projection.canonical_relay states, n is the network, N is one tag per NIP the face's NIP-11 document lists, R is one per limitation that document declares, t is one per shard the node claims under kind 30803, and the content is the NIP-11 document itself. It carries no rtt tag and nothing about uptime. A measurement somebody else took is worth more than a claim the subject published about itself, which is the rule the heartbeat already follows; liveness and latency are a NIP-66 monitor's to publish. The shape is discovery in constants.json and ref/discovery.py is the serialiser.

kind 30166 — a node's relay face, described for NIP-66 readers

{
  "kind": 30166,
  "pubkey": "<the node>",
  "tags": [
    ["d", "wss://pocketrelay.live"],                 // the endpoint, canonical
    ["n", "clearnet"],
    ["N", "1"], ["N", "11"], ["N", "40"], ["N", "59"], ["N", "77"],
    ["R", "!auth"], ["R", "!payment"], ["R", "!writes"], ["R", "!pow"],
    ["t", "bristol"],                           // a shard it claims
    ["expiration", "1789692000"]                // the descriptor's
  ],
  "content": "<the NIP-11 document the face serves>"
}
Bridge 2: NIP-85 & NIP-32 Reverse Reputation & Moderation Export
Internal peering uses cryptographic S1–S4 conformance reports (kind 30802). Nodes also export their subjective trust into standard client formats.
  • NIP-85 trusted assertions (kind 30385): a client-facing relay score a node MAY derive from its own kind 30802 reports and from nothing else. The event is merged NIP-85 as written. It is an identifier assertion whose d is the subject's relay URL in the canonical form projection.canonical_relay states in constants.json, and whose k is web, the NIP-73 type for a URL. A node publishes one per ws or wss endpoint the subject's descriptor declares. It is adverse only. A node never publishes a score for a peer it has not reported, because a favourable score would put on a relay the standing that blinded grants keep off it. rank is 100 times the multiplier the ladder applied: 50 for S1, 25 for S2, 0 for S3 and S4. p names the subject node and a cites the report by coordinate, so a client that wants the evidence is one fetch from it. It expires with the report. Clients choose whose to read with a kind 10040 provider list, under 30385:rank. PR #2418 proposes a differently shaped relay assertion under the same kind number and is unmerged; if it merges on another number a second serialiser follows it. ref/projection.py is the serialiser and scripts/interop-nostr-veil.py holds its output to an independent NIP-85 reader.
  • NIP-32 (Kind 1985): Emits standardized moderation classification labels (e.g. ["L", "fleetmesh.reputation"], ["l", "s1-divergence", "fleetmesh.reputation"]) consumable by third-party spam filters and client UI badge renderers.

kind 30385 — the relay score a client reads, projected from a kind 30802

{
  "kind": 30385,
  "pubkey": "<reporter node>",
  "tags": [
    ["d", "wss://relay.example.org"],                    // the subject's endpoint, canonical
    ["k", "web"],                                       // NIP-73: the identifier is a URL
    ["p", "<subject node>"],
    ["a", "30802:<reporter node>:<subject node>"],  // the report it is derived from
    ["rank", "25"],                                     // S2: 100 × 0.25
    ["expiration", "1787186400"]                        // the report's
  ],
  "content": ""
}
Bridge 3: NIP-90 Data Vending Machine (DVM) WASI Compute Gateway
Standard Nostr clients interact with compute providers using NIP-90 job requests (Kinds 5000–5999). A node running the ComputeProvider gateway maps each incoming NIP-90 request into a deterministic kind 30810 compute ask. It runs the job in the sandboxed fleetmesh-wasi-v1 runtime under strict fuel limits. Verified results come back as kind 6000–6999 DVM responses, with kind 7000 job status alongside.
Bridge 4: NIP-60 / NIP-61 Cashu Nutzap Asymmetric Settlement
For asymmetric peering topologies (e.g. resource-constrained mobile Leaf nodes or Edge relays consuming high inbound transit without reciprocal outbound bandwidth), peers can attach NIP-60 / NIP-61 Cashu Nutzap tokens to their peering proposals or window reconciliations. The provider accepts blinded ecash proofs to dynamically expand rate budget buckets without requiring symmetric data exchange.
Bridge 5: NostrHub Decentralized Specification Governance (Kind 30817)
To bypass centralized repository merge bottlenecks, the fleetmesh release pipeline formats the full specification, schema references, and test vectors into a canonical Kind 30817 Parameterized Replaceable Event published to NostrHub. The community reviews, verifies cryptographic test vectors, and attaches NIP-32 endorsement labels on-chain.
Zero Protocol Drift

Bridges run as non-blocking sidecars and ingress/egress filter adapters. The internal wire engine remains lean, mathematically rigorous, and completely decoupled from client-facing application layers.