Skip to content

commandlayer/runtime

Repository files navigation

CommandLayer Runtime

Reference Node.js runtime for CommandLayer Commons verbs. This service exposes deterministic verb handlers, signs receipts with Ed25519 via @commandlayer/runtime-core, and verifies receipts with a configured public key or an ENS lookup.

What is implemented

The runtime currently exposes:

  • GET / — JSON index with service metadata and enabled verb routes.
  • GET /health — health and signer/verifier readiness.
  • GET /healthz — alias for /health.
  • POST /verify — receipt hash/signature verification, with optional ENS lookup and optional schema validation.
  • POST /<verb>/v1.1.0 for the verbs enabled by ENABLED_VERBS.

The default enabled verbs are:

  • fetch
  • describe
  • format
  • clean
  • parse
  • summarize
  • convert
  • explain
  • analyze
  • classify

Debug routes

The runtime also implements these gated debug routes:

  • GET /debug/env
  • GET /debug/enskey
  • GET /debug/validators
  • POST /debug/prewarm

They are available only when both of these are set:

  • ENABLE_DEBUG=1
  • DEBUG_TOKEN=<token>

Requests must present the token either as Authorization: Bearer <token> or X-Debug-Token: <token>. When debug access is not enabled or the token is missing or wrong, these routes return 404.

There is no /debug/schemafetch route in the current implementation.

Receipt model

Verb routes return a JSON object with a signed receipt and optional unsigned runtime_metadata.

{
  "trace_id": "cltrace_...",
  "steps": [{ "step": 1, "receipt": { "...": "signed receipt" } }],
  "final_receipt": { "...": "same signed receipt" },
  "receipt": { "...": "signed receipt" },
  "runtime_metadata": {
    "trace": { "trace_id": "cltrace_...", "...": "optional" },
    "actor": { "...": "optional" },
    "delegation_result": { "...": "optional" }
  }
}

The signed receipt is produced by @commandlayer/runtime-core. The runtime sets proof fields under receipt.metadata.proof, including:

  • trace_id
  • receipt_id
  • alg
  • canonical
  • signer_id
  • kid
  • hash_sha256
  • signature_b64

For compatibility, if runtime-core returns metadata.proof.canonical, the runtime also emits metadata.proof.canonical_id in responses.

Signing behavior

At boot, the runtime requires signer configuration unless DEV_AUTO_KEYS=1 is set.

The canonical/current environment names shown in .env.example are:

  • RECEIPT_SIGNING_PRIVATE_KEY_PEM_B64
  • RECEIPT_SIGNING_PUBLIC_KEY_B64
  • RECEIPT_SIGNER_ID

The implementation also accepts several legacy aliases. See docs/CONFIGURATION.md for the exact precedence.

RECEIPT_SIGNING_PUBLIC_KEY_B64 is the current raw-32-byte Ed25519 public key input. RECEIPT_SIGNING_PUBLIC_KEY is not read by the server.

The runtime derives kid from the SHA-256 fingerprint of the active 32-byte public key. It does not read CL_KEY_ID or CL_CANONICAL_ID into production signing behavior.

Verification behavior

POST /verify accepts either:

  • a bare receipt, or
  • the wrapped verb response containing .receipt.

Supported query flags:

  • ens=1 — resolve the verification public key from ENS instead of using the configured local public key.
  • strict_kid=1 — with ens=1, require receipt.metadata.proof.kid to match the ENS cl.sig.kid TXT value when that TXT value is present.
  • refresh=1 — refresh ENS cache before verifying.
  • schema=1 — validate the receipt against the verb receipt schema.

When schema=1, schema validation uses the receipt verb to compute a v1.1.0 receipt schema URL under SCHEMA_HOST.

When a commons verb request omits execution, the runtime fabricates receipt execution defaults from the live route version: entry: "https://runtime.commandlayer.org/execute", verb: "<verb>", version: "1.1.0", and class: "commons". Commercial/payment-aware behavior belongs in the separate commercial runtime and is intentionally out of scope here.

When VERIFY_SCHEMA_CACHED_ONLY=1 (the default), /verify?schema=1 returns HTTP 202 with validator_not_warmed_yet if the validator for that verb has not been compiled yet. POST /debug/prewarm can queue validator warmup, and GET /debug/validators shows cache state.

If /verify exceeds VERIFY_MAX_MS, the runtime returns HTTP 502 with failure_type: "availability", retryable: true, and the message Verification service did not respond. Receipt may still be valid; retry recommended. Clients should treat that as transient service unavailability, not a cryptographic proof failure.

ENS verification inputs

When ens=1, the runtime resolves TXT records directly on the signer ENS name and reads:

  • cl.sig.pub by default, configurable via ENS_SIG_PUB_KEY
  • cl.sig.kid by default, configurable via ENS_SIG_KID_KEY
  • cl.sig.canonical by default, configurable via ENS_SIG_CANONICAL_KEY

The runtime does not read VERIFIER_ENS_NAME or ENS_SIGNER_TEXT_KEY.

cl.sig.pub must contain ed25519:<base64-raw32-public-key>.

Local development

Install

npm ci

This repository declares Node >=20.0.0 in package.json.

Configure

The fastest documented path is:

cp .env.example .env

Then populate the signing values from your own Ed25519 keypair, or run with DEV_AUTO_KEYS=1 for development-only ephemeral keys.

Start the server

npm start

Or use the helper script:

scripts/dev.sh

scripts/dev.sh generates keys.env with tools/mkkeys.mjs if needed, sources that file, enables debug routes, and starts server.mjs on 127.0.0.1:8099 by default.

Verify locally

curl -s http://127.0.0.1:8080/health | jq .
node scripts/smoke.mjs

CI and test surfaces

This repository's GitHub Actions workflows currently run:

  • npm ci
  • npm audit --audit-level=high
  • npm run check
  • npm test
  • scheduled and manual bash scripts/smoke-ens.sh

npm test runs Node unit tests plus tests/smoke.mjs.

Verification coverage

The production verification path is server.mjs, which signs receipts and verifies them via @commandlayer/runtime-core.

Repo-local test coverage now includes runtime service tests that exercise the receipt production path and POST /verify behavior directly, alongside the remaining legacy helper coverage under runtime/tests/.

Configuration and operations

About

CommandLayer Runtime: a reference HTTP runtime for CommandLayer verbs that validates schemas and issues signed, verifiable receipts using ENS key discovery and IPFS-backed schemas.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages