Primitives
I — Space
A named, prunable namespace of small, signed, self-expiring records. The catalog of what exists (services, active jobs, grants).
Two rules, enforced in code:
- Per-author monotonic
seq. A new record from an author supersedes its own lower-seqrecord at the same path. Records from different authors coexist. No clock is trusted for ordering — clock skew can’t let one node overwrite another. - TTL pruning. Records carry
expires_at;prune(now)drops expired ones.nowis passed in explicitly (no ambient clock).
RecordBody { space, author: NodeId, seq, path, expires_at, value: Vec<u8> }
value is a small inline payload (e.g. a ServiceCard) or a blob’s bytes.
II — Capsule
A WASM unit run deterministically, metered, deny-by-default, so its output is replay-verifiable. Determinism knobs:
consume_fuel— same code+input+fuel always interrupts at the same pointcranelift_nan_canonicalization— kills NaN-payload nondeterminism- relaxed SIMD off, threads off, no ambient WASI (no clock, randomness, fs, network)
Deny-by-default is enforced by pre-linking against exactly four curated host
functions — env.log, env.abort, env.blob_len, env.blob_read. A capsule
importing anything else (WASI included) fails to instantiate. The host ABI is a
core module exporting memory and run(in_ptr, in_len, out_ptr) -> out_len.
CapsuleRuntime::run(code, input, fuel_limit) -> RunOutcome { output, fuel_used }
Memory is capped (256 MiB/run); an infinite loop exhausts fuel and traps.
III — Pact
A signed, temporary agreement between only the parties involved. V0.1 ships one signed-transition engine + the Job transition table (Lease/Grant are the same engine with different tables). A Pact coordinates; it does not enforce — value moves via the payment adapter, evidence via the verifier.
The whole “smart contract” is a pure function:
job_transition(JobState, JobEvent) -> Result<JobState>
Offered → Accepted → Reserved → Running → Completed
├─ VerifyOk → Verified → Settled
└─ VerifyFail → Disputed → Refunded
A Receipt pins exactly what ran so a verifier can replay it:
ReceiptBody { pact, provider, capsule, input, output, runtime, fuel_used }
runtime is pinned (e.g. wasmtime-45.0.2/core/det2 — the exact patch version
comes from Cargo.lock at build time; no WASI is linked) — a receipt with an
unpinnable runtime is rejected. Replay re-runs the capsule on the input and
checks the output hash; mismatch ⇒ the provider lied.
Continue to Payments & ecash.