|
1 | | -# CommandLayer Runtime (Commons) |
| 1 | +# CommandLayer Runtime |
2 | 2 |
|
3 | | -Reference runtime for CommandLayer Commons verbs. |
| 3 | +Reference Node.js runtime for CommandLayer Commons verbs. This service executes deterministic verb handlers, signs receipts with Ed25519, and verifies receipts using local keys or ENS-discovered public keys. |
4 | 4 |
|
5 | | -## Endpoints |
6 | | -- GET /health |
7 | | -- GET /debug/env |
8 | | -- POST /fetch/v1.0.0 |
9 | | -- POST /verify |
| 5 | +## What this service does |
10 | 6 |
|
11 | | -## Example |
12 | | -RECEIPT=$(curl -s -X POST https://<YOUR_DOMAIN>/fetch/v1.0.0 \ |
| 7 | +- Exposes `POST /<verb>/v1.0.0` endpoints for Commons verbs (`fetch`, `describe`, `format`, `clean`, `parse`, `summarize`, `convert`, `explain`, `analyze`, `classify`). |
| 8 | +- Returns signed receipts containing: |
| 9 | + - deterministic result payloads, |
| 10 | + - execution trace metadata, |
| 11 | + - proof metadata (`alg`, canonical mode, SHA-256 hash, signature). |
| 12 | +- Exposes `POST /verify` to verify receipt hash/signature, and optionally validate schema + fetch public key from ENS. |
| 13 | +- Includes schema validator caching, warmup queueing, SSRF protections for `fetch`, and runtime safety budgets. |
| 14 | + |
| 15 | +## API overview |
| 16 | + |
| 17 | +### Core routes |
| 18 | + |
| 19 | +- `GET /` — service index with links and enabled verbs. |
| 20 | +- `GET /health` — process/service health and signer readiness. |
| 21 | +- `POST /<verb>/v1.0.0` — execute a single verb and return a signed receipt. |
| 22 | +- `POST /verify` — verify receipt integrity/signature; optional schema and ENS verification. |
| 23 | + |
| 24 | +### Debug routes |
| 25 | + |
| 26 | +> Debug routes are disabled by default. Enable with `DEBUG_ROUTES_ENABLED=1` and optionally protect with `DEBUG_BEARER_TOKEN`. |
| 27 | +
|
| 28 | +- `GET /debug/env` — effective runtime configuration. |
| 29 | +- `GET /debug/enskey` — ENS TXT key discovery state. |
| 30 | +- `GET /debug/schemafetch?verb=<verb>` — computed receipt schema URL. |
| 31 | +- `GET /debug/validators` — validator cache and warm-queue state. |
| 32 | +- `POST /debug/prewarm` — queue schema validator warmup. |
| 33 | + |
| 34 | +## Quickstart |
| 35 | + |
| 36 | +### 1) Install dependencies |
| 37 | + |
| 38 | +```bash |
| 39 | +npm install |
| 40 | +``` |
| 41 | + |
| 42 | +### 2) Generate an Ed25519 keypair (for local signing) |
| 43 | + |
| 44 | +```bash |
| 45 | +openssl genpkey -algorithm Ed25519 -out private.pem |
| 46 | +openssl pkey -in private.pem -pubout -out public.pem |
| 47 | + |
| 48 | +export RECEIPT_SIGNING_PRIVATE_KEY_PEM_B64="$(base64 -w0 < private.pem)" |
| 49 | +export RECEIPT_SIGNING_PUBLIC_KEY_PEM_B64="$(base64 -w0 < public.pem)" |
| 50 | +export RECEIPT_SIGNER_ID="runtime.local" |
| 51 | +``` |
| 52 | + |
| 53 | +> macOS note: replace `base64 -w0` with `base64 | tr -d '\n'`. |
| 54 | +
|
| 55 | +### 3) Start the runtime |
| 56 | + |
| 57 | +```bash |
| 58 | +npm start |
| 59 | +``` |
| 60 | + |
| 61 | +Default port is `8080` (override with `PORT`). |
| 62 | + |
| 63 | +### 4) Verify startup |
| 64 | + |
| 65 | +```bash |
| 66 | +curl -s http://localhost:8080/health | jq . |
| 67 | +``` |
| 68 | + |
| 69 | +You should see `"ok": true` and `"signer_ok": true`. |
| 70 | + |
| 71 | +## Example flow |
| 72 | + |
| 73 | +### Request a fetch receipt |
| 74 | + |
| 75 | +```bash |
| 76 | +RECEIPT=$(curl -s -X POST "http://localhost:8080/fetch/v1.0.0" \ |
| 77 | + -H "Content-Type: application/json" \ |
| 78 | + -d '{ |
| 79 | + "x402": { |
| 80 | + "entry": "x402://fetchagent.eth/fetch/v1.0.0", |
| 81 | + "verb": "fetch", |
| 82 | + "version": "1.0.0" |
| 83 | + }, |
| 84 | + "source": "https://example.com" |
| 85 | + }') |
| 86 | + |
| 87 | +printf '%s\n' "$RECEIPT" | jq . |
| 88 | +``` |
| 89 | + |
| 90 | +### Verify the receipt locally |
| 91 | + |
| 92 | +```bash |
| 93 | +printf '%s' "$RECEIPT" | curl -s -X POST "http://localhost:8080/verify" \ |
| 94 | + -H "Content-Type: application/json" \ |
| 95 | + -d @- | jq . |
| 96 | +``` |
| 97 | + |
| 98 | +### Verify with ENS public key lookup |
| 99 | + |
| 100 | +```bash |
| 101 | +printf '%s' "$RECEIPT" | curl -s -X POST "http://localhost:8080/verify?ens=1" \ |
13 | 102 | -H "Content-Type: application/json" \ |
14 | | - -d '{"x402":{"entry":"x402://fetchagent.eth/fetch/v1.0.0","verb":"fetch","version":"1.0.0"},"source":"https://example.com"}') |
| 103 | + -d @- | jq . |
| 104 | +``` |
| 105 | + |
| 106 | +## Verification semantics |
| 107 | + |
| 108 | +`POST /verify` supports query flags: |
| 109 | + |
| 110 | +- `ens=1` — fetch verifier pubkey from ENS TXT record (`VERIFIER_ENS_NAME`, `ENS_PUBKEY_TEXT_KEY`). |
| 111 | +- `refresh=1` — bypass ENS cache and refresh lookup. |
| 112 | +- `schema=1` — validate receipt against verb schema. |
| 113 | + |
| 114 | +When `VERIFY_SCHEMA_CACHED_ONLY=1` (default), schema validation is edge-safe: |
| 115 | + |
| 116 | +- if validator is warm: request is fully validated, |
| 117 | +- if validator is cold: service returns `202` with `validator_not_warmed_yet` and queues async prewarm. |
| 118 | + |
| 119 | +Use `POST /debug/prewarm` and `GET /debug/validators` for schema prewarming workflows. |
| 120 | + |
| 121 | +## Configuration |
| 122 | + |
| 123 | +Detailed environment variable documentation lives in [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md). |
| 124 | + |
| 125 | +## Development checks |
| 126 | + |
| 127 | +```bash |
| 128 | +npm run check |
| 129 | +npm test |
| 130 | +``` |
| 131 | + |
| 132 | +`npm test` runs an automated smoke suite for signer readiness, verb execution, verify pass/fail paths, and debug route auth. |
| 133 | + |
| 134 | +## Security notes |
| 135 | + |
| 136 | +- `fetch` only allows `http(s)` URLs. |
| 137 | +- SSRF guard blocks localhost/private IP ranges and DNS resolutions to private ranges. |
| 138 | +- Optional host allowlist (`ALLOW_FETCH_HOSTS`) can strictly bound outbound `fetch`. |
| 139 | +- Request-level limits are capped by server-side `SERVER_MAX_HANDLER_MS`. |
| 140 | +- `/verify` execution is bounded by `VERIFY_MAX_MS`. |
| 141 | + |
| 142 | +## Operational notes |
| 143 | + |
| 144 | +- Validator/schema caches are in-memory (per process). |
| 145 | +- Prewarm is best-effort and asynchronous. |
| 146 | +- In multi-replica deployments, warm each replica independently. |
| 147 | + |
| 148 | +See [`docs/OPERATIONS.md`](docs/OPERATIONS.md) for deployment and runbook guidance. |
| 149 | + |
| 150 | +## Engineering review artifacts |
15 | 151 |
|
16 | | -printf '%s' "$RECEIPT" | curl -s -X POST "https://<YOUR_DOMAIN>/verify?ens=1" \ |
17 | | - -H "Content-Type: application/json" -d @- |
| 152 | +For a focused codebase review (strengths, risks, and prioritized improvements), see [`docs/REVIEW.md`](docs/REVIEW.md). |
0 commit comments