Fleetmesh fleetmesh

The fleetmesh Protocol · part 7 of 10

Compute market

Verifiable confidential compute execution, cryptographic attestations, and direct Lightning settlement.

Compute market

Confidential Compute Market Architecture

A node with a cryptographic DID, proven track record, and authenticated messaging channel possesses the prerequisites for decentralized compute. Fleetmesh leverages this foundation to create an open compute market without central coordination.

This is not the settlement question

§ Grants & receipts defers payment for transit, and that stands. Transit is continuous, fungible, and its scarcity is unproven; a market for it would be priced against a demand curve nobody has measured. A compute job is the opposite: discrete, specified in advance, with a natural unit and a moment of completion. The two are different economic objects and only one of them is ready. The three rules from that section bind here without exception — most importantly, money buys compute and never buys standing.

Why there is no fee to charge

Traditional marketplaces extract transaction fees by monopolizing four services: identity (counterparty authentication), reputation (historical tracking), discovery (order book matching), and settlement (escrow and clearing). Transaction fees represent the cost of proprietary access to these four functions.

In this network all four already exist as public infrastructure, and none of them belongs to anyone:

What a venue normally sells What replaces it here
identity Every participant already has a did:nostr node identity, resolvable by anyone, with no account and no signup.
reputation Kind 30802 conformance reports, weighted locally per § Trust weighting. Evidence-backed and portable — a seller's record is not held hostage by the venue it was earned on.
discovery Signed offers and asks on gossipsub and on relays. Anyone may index the order book; nobody can be the only index.
settlement Lightning, with delivery and payment coupled — accountably, not atomically — by the construction below. No escrow agent exists, so none can be paid.

The absence of fees is a structural property rather than a policy choice. Because all four marketplace functions run on open protocols, there is no centralized service left to charge a fee. Third parties may still construct value-added venues (such as curated indexing or UI frontends) and charge for their services. However, they cannot monopolize access: the order book is a public topic, and reputation consists of signed events held across the mesh.

The job, and why WASM

Two executors are defined, and the difference between them is not power but verifiability:

wasm
A WebAssembly module, content-addressed, run against content-addressed inputs under a restricted WASI surface: no ambient clock, no network, no randomness the job did not supply. Given the same module and the same inputs, every honest executor produces the same output bytes — so the output hash is checkable by re-running, by anyone, afterwards. This is the default and the only executor whose results a buyer can verify without trusting the seller.
bacalhau
An adapter for compute-over-data engines and containerized workloads. Inputs and outputs remain content-addressed. Because execution determinism is not guaranteed, results carry the same accountable delivery as any other job but no mathematical reproducibility. Buyers MUST NOT file adverse correctness reports against non-deterministic executors based solely on result hash divergence.

fleetmesh does not implement an execution engine and should never grow one. It specifies the envelope: what a job is, how it is priced, how it is paid for, and what evidence a dispute needs. Executors sit behind a stable interface, as adapters. A third executor that arrives with better determinism guarantees should require no change here.

The price unit has to be objective

Quotes are only comparable if they are quoted in something both sides can count. Wall-clock seconds are not that: they measure the seller's hardware, not the work. For the wasm executor the unit is fuel: the runtime's metered instruction count. Fuel is a deterministic function of the module and its inputs, so it is identical on every honest executor. A price is millisatoshis per million fuel units, plus a declared ceiling.

Two things follow that ordinary cloud pricing cannot offer. A buyer can know the cost before paying, by metering a dry run locally or accepting the seller's committed fuel bound. And two quotes are directly comparable, because the denominator is a property of the job rather than of the machine. Bacalhau jobs price per resource-second instead and are explicitly marked as estimates, because that is what they are.

What the order book may see

An ask has to reach sellers the buyer has not chosen yet, which is what makes it a market rather than a purchase order. It does not have to say what the job is. Those are separable, and this document separates them.

Everything a seller needs to price the work is structural: the executor, the engine, the fuel ceiling, the input length, the deadline and the verification mode. Everything that identifies the work — the module digest and the input digest — is needed only by the seller that wins. So the ask carries the first set and a commit over the second, and the job itself travels in compute/1.0/accept, encrypted to one seller after it has won.

The leak this closes

The obvious shape for this market is an ask naming the module and input, and a receipt naming them again alongside the result, the price and the payer. Chained, those two are a permanent public log of who computed what, over whose data, for how much. A module digest alone identifies the computation — a node running compute:spam-classifier/1.0 hourly would announce its moderation posture to anyone indexing the topic.

§ Grants & receipts went to considerable trouble to keep exactly this out of the peering graph: blinded pair identifiers, grants encrypted to the subject, clean windows never published. A compute market published in the clear beside it would hand back everything that bought. The construction here is not new — it is the kind 30801 envelope, reused.

Two things survive that a naive reading might expect to break. Price discovery is unaffected, because quotes are priced against the declared fuel_max ceiling, which is exactly what § The price unit already said a buyer commits to. And the buyer can still re-run its own jobs, because the buyer holds the plaintext. What it does mean is that a third party cannot re-run a job it was not given — which is why the next section stops treating re-execution as the only way to be sure.

Paying without an escrow agent

The oldest problem in trade: whoever moves first can be robbed. Lightning solves it here without a third party, because a payment already reveals a secret when it settles.

1 · ask published 2 · quotes returned 3 · job executed 4 · result sealed 5 · payment reveals k 6 · verified, per mode kind 30810, gossipsub DIDComm compute/1.0 deterministic wasm invoice hash = SHA256(k) buyer decrypts with k re-run, or a proof only if the hashes disagree → kind 30802, evidence = the seller’s own signed result hash
Steps 4 and 5 are tightly coupled, but not atomic. Settling the invoice forces k onto the wire, so payment and key disclosure happen together — which is not the same as the key opening the ciphertext. What does hold is that no third party holds anybody’s money in between, and that a seller who discloses a useless key has signed evidence against itself before it was paid.
The swap is not atomic, and this document does not claim it is

Settling an invoice forces the seller to reveal an HTLC preimage. Standard Lightning payments do not cryptographically bind preimages to decrypted payloads. A malicious seller could encrypt data with key k₁, invoice for the preimage of k₂, collect payment, and deliver an invalid decryption key.

This represents the classic zero-knowledge contingent payment problem. Closing this gap cryptographically requires zk-SNARK proofs of plaintext well-formedness, which are computationally prohibitive for lightweight nodes. Consequently, on-wire Lightning delivery is not strictly atomic.

What replaces atomicity: signing the claim before taking the money

The gap is closable without a proof system, by making a failed delivery provable rather than preventable. Before the buyer pays anything, the seller sends a signed compute/1.0/sealed naming three things at once:

compute/1.0/sealed — signed, and sent before payment

{
  "ciphertext":   "<sha256 of the bytes the buyer was handed>",
  "payment_hash": "<SHA256(k) — the invoice the buyer is about to pay>",
  "result":       "<sha256 of the plaintext that k is claimed to reveal>",
  "fuel_used":    2311904772
}

Now the seller has committed, under its own signature and before receiving anything, that this ciphertext opens under the preimage of this invoice to a plaintext with that hash. A buyer who pays and cannot decrypt, or who decrypts to something whose hash does not match, holds the seller’s signed statement and the contradicting bytes. That is precisely the evidentiary standard § Severity ladder already demands, and it makes taking payment for a useless key an S3 rather than an unprovable dispute.

Accountable, not atomic — and the difference is real

A buyer can still be defrauded once, per seller, and recovers nothing: the payment is gone and the remedy is reputational. That is strictly weaker than atomicity, and it is the honest position for a specification that has declined to require ZKCP. It is also the same bargain the rest of this document makes everywhere — misbehaviour is priced after the fact, not prevented — so at least it is consistent. An implementation wanting genuine atomicity needs the contingent-payment proof, and that remains a named direction rather than a requirement.

Pluggable Execution Runtimes (ComputeExecutor)

To prevent vendor lock-in to a single WebAssembly runtime engine, execution environments are abstracted behind the async ComputeExecutor trait. Sellers can run Wasmtime, Wasmer, WasmEdge, or distributed container runners (Bacalhau) as pluggable drivers.

crates/mesh — Modular Compute Runtime Trait

#[async_trait]
pub trait ComputeExecutor: Send + Sync + 'static {
    /// Runtime engine identifier (e.g. "wasmtime", "wasmer", "v8", "bacalhau")
    fn engine_id(&self) -> &'static str;

    /// SHA-256 digest of the standardized WASI capability profile
    fn wasi_profile_digest(&self) -> [u8; 32];

    /// Estimate fuel and provide a deterministic price quote
    async fn quote(&self, module_bytes: &[u8], limits: &ComputeLimits)
        -> Result<ComputeQuote, ComputeError>;

    /// Execute a verified module with metered fuel limits
    async fn execute(&self, module_bytes: &[u8], inputs: &[u8], fuel_cap: u64)
        -> Result<ComputeExecutionResult, ComputeError>;
}

Standardized Deterministic Capability Profile (fleetmesh-wasi-v1)

Executing untrusted stranger bytecode requires rigorous, capability-based sandboxing and mathematical determinism. fleetmesh defines the fleetmesh-wasi-v1 standard profile that every WASM executor MUST enforce:

Capability Domain Restriction / Policy Deterministic & Security Guarantee
Network I/O network: none All socket creation, outbound DNS, TCP/UDP connects, and HTTP bindings are strictly disabled. The module cannot communicate outside the host sandbox.
Filesystem fs: memory-only No host filesystem directories are mapped. The module receives only its input blob buffer in memory and writes output to its return buffer.
Clocks & Time clock: virtual System wall-clocks return the deterministic Unix timestamp of the job's created_at event. Real-time drift cannot cause execution divergence.
Entropy / PRNG prng: seeded Random number generators are deterministically seeded with SHA256(module_digest || input_digest), ensuring repeatable bitwise execution across disparate nodes.
Resource Limits memory ≤ max_bytes, fuel ≤ max_fuel Instruction counting traps and halts runaway infinite loops; linear memory bounds prevent host out-of-memory crashes.

Profile Digest: An executor computes the SHA-256 hash of its canonical profile configuration document, publishing it as the fourth element in its runtime tag: ["runtime", "wasmtime", "18.0.0", "<wasi_profile_digest>"]. Buyers verify this digest to ensure the seller executes in an identical, secure sandbox before submitting paid tasks.

Correctness is a mode, declared before the work

The shape is unchanged from § Severity ladder: your signed claim against my measurement, with divergence as the offence. A false result hash is a misreport, which is an S2; a seller that returns fabricated results at scale is an S3. The evidence requirement is satisfied by construction, because the seller signed the result hash in order to get paid for it.

What the shape does not fix is how that measurement is taken. Re-execution is a fine mechanism and a poor requirement: it obliges whoever adjudicates to hold the plaintext, which is precisely what a confidential job will not give them. So the mechanism is named in the ask, before the work happens, the same way a grant names its remedy before the breach. The verify tag was already there and already declared up front; it now has a vocabulary.

ModeWhat a dispute admits as evidenceNeeds the plaintext?
sample an independent re-run contradicting the seller-signed result hash yes
dual two executors returning different hashes for one job yes
proof the proof fails to verify against the module and input commitments no
none delivery only — the sealed commitment against the disclosed preimage no

A refutation citing evidence the declared mode does not admit is not a finding. This is not a courtesy to sellers; it is what stops a buyer choosing the cheapest verification and then litigating as though it had bought the strongest.

Sampling rate remains the buyer's choice and its own cost. Verifying everything doubles the compute bill and defeats the purpose of buying it; verifying nothing means a seller learns that lying is free. The arithmetic is worth doing rather than asserting: at sampling rate p, catching a seller who cheats on a fraction f of jobs with confidence c takes ln(1-c) / ln(1-pf) jobs. At p = 0.05 against a seller cheating every job that is about 45 jobs for 90% confidence — fast only if the buyer actually sends 45 jobs. Against one cheating a tenth of the time it is roughly 450. Any claim faster than that — "within a working day", say — is smuggling in a job rate it has not stated.

Verifiable work units, and why they close the loop

Sampling is probabilistic, and the arithmetic above is the honest description of what that costs. Under proof the seller returns evidence that the committed module, run on the committed input, produced the committed result. The buyer verifies without re-running. Nobody re-runs at all.

That is worth having on its own, but the reason it belongs in this document is that it is the same change as the section above. Confidentiality is only affordable if correctness does not require re-execution, and correctness only stops requiring re-execution if the unit carries its own proof. They are one property, not two. A proof-mode receipt can be adjudicated by a third party who never sees the job, which is the thing no amount of sampling can offer.

The cost is real and should not be soft-pedalled. Proving costs orders of magnitude more than executing, and it inverts the pricing argument: msat_per_mfuel prices execution, and a prover's bill is not proportional to the fuel it is proving about. So proof ships as an expressible mode with no reference implementation, on the same footing this document already gives contingent payment — a named direction rather than a requirement.

Proving is itself a job this market can sell

Proof generation is deterministic, expensive, content-addressed, and metered in a unit both sides can count. It is an unusually good fit for the executor this document already specifies, and compute:zk-verify-groth16/1.0 already exists as a job type. A seller without a prover can buy one from a seller that has one, priced in the same units and disputed by the same ladder. The market can pay for its own verification, which is a considerably better answer than mandating a proof system nobody has deployed.

Dual-Execution Cross-Validation Protocol ("I'll run it if you do too")

Decentralized compute faces a classic cold-start challenge: proving a new worker's competence without exposing buyers to financial loss or corrupt results.

Because the fleetmesh-wasi-v1 execution environment guarantees bitwise output determinism, the network supports dual-execution cross-validation:

Stage Action & Protocol Flow Outcome & Reputation Invariant
1. Co-Dispatch Buyer or mediator dispatches a deterministic job across two workers: Worker A (candidate / newcomer) and Worker B (established trusted anchor or buyer local runner). Both workers execute identical (module, input) tuples under the standard fleetmesh-wasi-v1 profile in parallel.
2. Result Matching Buyer compares result hashes: SHA256(Result_A) == SHA256(Result_B). Match: the result stands and the job settles normally. It earns Worker A nothing — completed jobs MUST NOT raise a tier or feed the trust weighting (buying standing, below). What a match buys belongs to the buyer: a result from an untested seller it can rely on.
Mismatch: one of the two is wrong, and the pair alone does not say which. The buyer re-runs, or dispatches to a third executor; the executor the majority contradicts is the S2 misreport on topic: compute, notice first like any S2.
3. Mutual Peer Verification During idle periods, peer nodes cross-verify each other on synthetic verification suites ("I'll run it if you do too"). A mismatch on a synthetic job is evidence like any other; a match is not, because clean results are never published. Calibration with no escrow, no arbiter, and no positive attestation.

Modular AI & LLM Inference Routing (InferenceProvider)

WASM execution handles deterministic, bitwise-verifiable compute. Modern AI workloads — language models, image generation, voice transcription — are non-deterministic. Floating-point GPU variance, temperature sampling and model quantisation each break reproducibility. Strict bitwise hash-matching does not apply to generative LLM outputs.

Rather than forcing non-deterministic AI into the deterministic fuel engine, fleetmesh abstracts AI inference behind the modular InferenceProvider adapter interface. Nodes can run local GPU workers or bridge into specialized decentralized inference marketplaces such as Routstr (OpenAI-compatible routing over Nostr & Cashu) and NIP-90 Data Vending Machines (DVMs).

crates/mesh — Modular Inference Trait

#[async_trait]
pub trait InferenceProvider: Send + Sync + 'static {
    /// Provider scheme identifier (e.g. "routstr", "nip90", "ollama", "vllm")
    fn provider_id(&self) -> &'static str;

    /// List active models served by this provider
    async fn list_models(&self) -> Result<Vec<ModelDescriptor>, InferenceError>;

    /// Estimate cost/rate per token for a given model
    async fn estimate_cost(&self, model: &str, prompt_tokens: u32)
        -> Result<InferenceQuote, InferenceError>;

    /// Stream completions over an authenticated session
    async fn complete(&self, req: &InferenceRequest)
        -> Result<Box<dyn InferenceStream>, InferenceError>;
}
Provider Scheme Protocol / Standard Settlement & Capabilities
routstr Routstr Protocol (OpenAI-compatible API) Streaming token inference (/v1/chat/completions) authenticated and paid per-request via Cashu ecash (NUTs) tokens or Lightning streaming.
nip90 NIP-90 Nostr Data Vending Machines Asynchronous request/response jobs across text, image (Flux/SD), speech, and translation using Nostr DVM events (kinds 5000–5999) with Lightning invoices.
ollama / vllm Local GPU Runner Engine Direct local execution on node-attached GPUs (NVIDIA CUDA / Apple Metal) for zero-latency private inference with local rate limiting.

Wire formats

Three kinds, verified free by the same method as the others on 2026-08-29 and listed in § Registration. Quotes are deliberately not events: a quote is addressed to one buyer and travels over compute/1.0, so a seller's pricing to one counterparty is not a public commitment to all of them.

kind 11803 — compute offer, one per selling node

{
  "kind": 11803,
  "tags": [
    ["executor", "wasm",     "msat_per_mfuel", "45"],
    ["executor", "bacalhau", "msat_per_cpu_s", "900", "estimate"],
    ["limit", "max_fuel",   "50000000000"],
    ["limit", "max_bytes",  "1073741824"],
    ["limit", "concurrent", "4"],
    ["pay", "bolt11"], ["pay", "bolt12", "<offer>"],
    ["runtime", "wasmtime", "<version>", "<wasi profile digest>"],
    ["expiration", "1789000000"]
  ],
  "content": ""
}

kind 30810 — compute ask: an order book entry, not a job specification

{
  "kind": 30810,
  "tags": [
    ["d", "<ask id>"],
    ["commit", "<sha256 of the job spec, which is not published>"],
    ["executor", "wasm"],
    ["runtime", "wasmtime", "18.0.0", "<wasi profile digest>"],
    ["fuel_max", "2500000000"],       // what a quote is priced against
    ["input_size", "1048576"],
    ["bid", "msat_per_mfuel", "50"],
    ["deadline", "1787004000"],
    ["verify", "proof", "risc0-v1"],  // declared up front, so it is not a surprise
    ["expiration", "1787004600"]
  ],
  "content": ""
}

kind 30811 — job receipt: the same envelope shape as a grant

{
  "kind": 30811,
  "tags": [
    ["d", "<blinded job identifier — only buyer and seller can derive it>"],
    ["commit", "<commitment to the receipt, which is encrypted in content>"],
    ["scheme", "sha256-blind/1", "nip44/2"],
    ["expiration", "1789600000"]
  ],
  "content": "<nip44 ciphertext to the buyer: ask, module, input, result,
              fuel_used, paid_msat, payment_hash, executor, proof>"
}

The result inside that ciphertext is still the verification anchor: a falsifiable claim, and the same value the seller committed to in the pre-payment sealed message. What has changed is who can read it. A receipt is a record of a job that went right, and § Grants & receipts already established that this protocol does not publish those — positive events are inert under the trust weighting and broadcasting them leaks topology for nothing. The argument does not stop applying because the subject is compute.

A seller MAY publish a cleartext receipt where the buyer has consented. Some buyers want a public record of work done on their behalf. That is their disclosure to make, and the point is that it is a choice rather than the default.

Modular Settlement Rails & Zero-Custody Payments (PaymentRail)

A node should not need custody of funds to participate, nor should it be hardwired to a single proprietary payment daemon. fleetmesh abstracts all payment generation, verification, and settlement behind the PaymentRail adapter interface.

Settlement Rail Protocol / Standard Properties & Role
ipd / ilp Interledger Payment Daemon (IPD / Open Payments) Universal, open-source multi-rail settlement routing streaming micro-payments across heterogeneous financial and crypto networks (ILP STREAM).
nwc NIP-47 Nostr Wallet Connect Zero-custody client-to-wallet protocol. The node holds a connection secret, not a private key, instructing the user's remote wallet to pay discrete invoices up to a budgeted cap.
bolt11 / bolt12 Native Lightning (LND, CLN, LDK) Direct Lightning Network hold-invoices and reusable BOLT12 offers for high-volume peerings and compute settlements.
cashu / fedimint Chaumian E-Cash (NUTs) Instant, private, zero-routing-fee blind tokens for rapid micro-compute settling without opening channels or maintaining liquidity.
Honest costs

No rake is not no cost. A buyer pays network routing fees, the compute it spends on verification re-runs, and the mesh capacity the job consumes under its own grant. A seller pays for inbound liquidity and electricity. Those are real and they are all paid to somebody who did something. The claim is narrow and worth keeping narrow: nothing is paid to a party whose only contribution is standing between the two of you.

What is likely to go wrong

Problem Where it stands
thin order book An open book with no market maker and few participants has terrible spreads. Early on this is a bulletin board, not an exchange, and it should be described that way rather than dressed up.
wasm determinism is not free Floating point, SIMD, threads and any ambient capability can break reproducibility. The runtime tag pins the engine and a WASI profile digest for this reason, and a buyer comparing hashes across differing profiles is comparing nothing.
the job is the attack A seller runs a stranger's code. Sandboxing is the executor's problem, not this specification's, but a node MUST treat resource limits as security boundaries and not as billing hints.
privacy of inputs The order book does not see the job — the module and input reach only the winning seller (§ What the order book may see). That seller does see them, and hiding a job from the node executing it needs a TEE, which § Scope refuses. The honest guidance is unchanged in the one direction that matters: a job is work you do not mind your chosen counterparty reading, and verify mode decides who else must read it to adjudicate a dispute.
buying standing Watched deliberately. Completed jobs MUST NOT raise a node's tier and MUST NOT feed the trust weighting. A wealthy participant can buy a great deal of compute and not one unit of reputation.