Under 5 minutes. Live runtime. Real Ed25519 signatures. CommandLayer standardizes what agents do by pinning request/receipt schemas to canonical ENS names. You keep the same contract as runtimes, facilitators, and payment rails evolve.
POST /clean/v1.1.0 → get { receipt, runtime_metadata? } → treat receipt as the canonical contract and runtime_metadata as optional.
This is a real runtime endpoint. Send the pinned Commons request shape and get back a canonical receipt. Start with clean — it's deterministic, making verification feel real on the first run.
clean first? It's deterministic. The output is predictable so you can confirm the hash, the signature, and the receipt shape without chasing AI output variance. Try summarize or analyze after your first verified receipt.
curl -sS --max-time 20 \ -X POST 'https://runtime.commandlayer.org/clean/v1.1.0' \ -H 'Content-Type: application/json' \ --data-binary '{ "verb": "clean", "schema_version": "1.1.0", "content": " hello world ", "operations": ["collapse_whitespace", "trim"] }'
curl https://runtime.commandlayer.org/health first to confirm availability.
Commons defines the minimum verifiable receipt contract. Start with receipt first. Treat runtime_metadata as optional execution context that never changes the canonical shape.
{
"verb": "clean",
"schema_version": "1.1.0",
"status": "success",
"cleaned_content": "hello world",
"operations_applied": ["collapse_whitespace", "trim"]
}
runtime_metadata, treat it as optional execution-layer context around the receipt. The canonical receipt above is the only shape you need to validate the Commons contract.
Each agent publishes machine-readable ENS TXT records. That's how discovery tools and clients find the canonical entrypoint, schema URLs, and receipt verification keys. For Commons v1.1.0, entry is the shared HTTP execute surface.
# live ENS records · fetchagent.eth (15 TXT + 1 address) # verb identity cl.verb fetch cl.version 1.1.0 cl.class commons # entrypoint cl.entry https://runtime.commandlayer.org/execute # schemas (HTTP mirror) cl.schema.request https://commandlayer.org/schemas/v1.1.0/commons/fetch/fetch.request.schema.json cl.schema.receipt https://commandlayer.org/schemas/v1.1.0/commons/fetch/fetch.receipt.schema.json # schemas (IPFS — immutable, content-addressed) cl.cid.schemas bafybeifp4oxgofktbqh5tua2xrpsb5gfrktrtesqxq67i2tefavqxjpxb4 cl.schemas.mirror.ipfs ipfs://bafybeifp4oxgofktbqh5tua2xrpsb5gfrktrtesqxq67i2tefavqxjpxb4 cl.schemas.checksums.ipfs ipfs://bafybeifp4oxgofktbqh5tua2xrpsb5gfrktrtesqxq67i2tefavqxjpxb4/checksums.txt # agent card cl.agentcard https://commandlayer.org/agent-cards/agents/v1.1.0/commons/fetchagent.eth.json cl.cid.agentcards bafybeiht6qske34o3te5kfd6d3qspneiagb2nxaneae5s66vr7hda4kzr4 cl.agentcards.checksums.ipfs ipfs://bafybeiht6qske34o3te5kfd6d3qspneiagb2nxaneae5s66vr7hda4kzr4/checksums.txt # ownership & signing cl.owner commandlayer.eth cl.receipt.alg ed25519 cl.receipt.signer_id runtime.commandlayer.eth # address record eth 0x298A01ec0c6234406622494ae96AA6A20c12AE90
If your runtime includes a proof block, verification is intentionally boring: hash → signature. Full verification adds: schema validation + ENS key resolution. The digest is computed from the canonical receipt only — runtime metadata stays outside the hash.
npm install tweetnacl tweetnacl-util
import nacl from "tweetnacl"; import { decodeBase64 } from "tweetnacl-util"; import crypto from "crypto"; // Deterministic canonicalization — sort keys, no spaces function canonicalize(value) { if (Array.isArray(value)) return `[${value.map(canonicalize).join(",")}]`; if (value && typeof value === "object") return `{${Object.keys(value).sort() .map(k => `${JSON.stringify(k)}:${canonicalize(value[k])}`) .join(",")}}`; return JSON.stringify(value); } /** * Minimal receipt verification: * 1) canonicalize receipt bytes deterministically * 2) sha256 over canonical bytes * 3) verify detached Ed25519 signature from runtime_metadata.proof */ export function verifyReceiptMinimal(envelope, publicKeyBytes) { const receipt = envelope?.receipt || envelope; const proof = envelope?.runtime_metadata?.proof; if (!proof?.signature_b64 || !proof?.hash_sha256) return { ok: false, reason: "missing detached proof" }; const canonical = canonicalize(receipt); const hashHex = crypto.createHash("sha256") .update(canonical, "utf8").digest("hex"); if (hashHex !== proof.hash_sha256) return { ok: false, reason: "hash mismatch" }; const hashBytes = Buffer.from(proof.hash_sha256, "hex"); const sigBytes = decodeBase64(proof.signature_b64); const ok = nacl.sign.detached.verify(hashBytes, sigBytes, publicKeyBytes); return ok ? { ok: true } : { ok: false, reason: "signature invalid" }; }