Skip to content

Commit ae925c6

Browse files
committed
Scaffold full commandlayer/router production implementation
Implements the complete CommandLayer Router as a production-grade TypeScript repo from scratch on the feature branch. ## What's included ### Core - POST /run/v1.0.0 supporting explicit plan mode and scored mode (no LLM) - Deterministic score function: 0.40*relevance + 0.30*need_bonus + 0.10*novelty + 0.10*cost_penalty + 0.10*risk_penalty; tie-break alphabetical - Prerequisite graph: fetch→clean→summarize→classify→parse→analyze→format - Schema-shaped request builders per verb (fetch special: x402+source only) - Append-only RunState: artifacts, trace, decisions - Stop conditions: final artifact, score<=0, max_steps, timeout, max_receipts ### Infrastructure - Ed25519 + SHA-256 + json.sorted_keys.v1 receipt signing/verification - ENS TXT pubkey resolution for runtime.commandlayer.eth (?ens=1) - AJV schema warm queue (background, non-blocking); POST /debug/prewarm → 202 - /verify?schema=1: cached-only mode returns 202 + retry_after_ms - SSRF guard for fetch: blocks private IPs, localhost, IPv6, metadata service - In-memory idempotency cache with SHA-256 key derivation - NDJSON replay logs per run; GET /replay/:run_id endpoint - HTTP delegate mode via RuntimeClient (RUNTIME_URL env) - Local reference handlers for demo/test (no RUNTIME_URL needed) - CLI: cl-router run --goal/--content/--source/--plan ### ENS Anchors (source of truth embedded) - runtime.commandlayer.eth: alg=ed25519, kid=v1, canonical=json.sorted_keys.v1 - cleanagent.eth: canonical example of Commons agent TXT record shape ### Tests (37 passing) - scoring: verb selection, policy, stop conditions, tie-break, novelty penalty - prereqs: all 10 verbs, conditions, edge cases - requestBuilders: fetch vs non-fetch schema shapes, idempotency_key, limits - idempotency: cache hit/miss, null result, stable stringify - engine: scored/explicit modes, conditions, optional steps, unique run_ids ### Docs - SPEC.md: full /run/v1.0.0 spec, score function, prereq graph, state model - API.md: all endpoints + env vars reference - CONTRACTS.md: RunRequest/RunResponse/RunState types, receipt expectations - INTEGRATION_RUNTIME.md: HTTP delegate and drop-in block patterns - INTEGRATION_SITE.md: site docs update guide - EXAMPLES.md: curl/CLI/SDK usage examples with ENS anchor reference https://claude.ai/code/session_01TjunT4KVR59QhARYaw2nUE
1 parent 270494a commit ae925c6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+5249
-1
lines changed

.env.example

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Router -> Runtime HTTP base (required for HTTP runtime mode)
2+
RUNTIME_URL=https://runtime.commandlayer.org
3+
4+
# Port to listen on (default: 8080)
5+
PORT=8080
6+
7+
# Where to write NDJSON run logs
8+
RUN_LOG_DIR=run-logs
9+
10+
# Receipt signing private key (one of these must be set for signing)
11+
# RECEIPT_SIGNING_PRIVATE_KEY_PEM=-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----
12+
# RECEIPT_SIGNING_PRIVATE_KEY_B64=<base64-encoded raw private key bytes>
13+
14+
# ENS resolution for ?ens=1 verify mode
15+
ETH_RPC_URL=https://eth-mainnet.g.alchemy.com/v2/your-key
16+
VERIFIER_ENS_NAME=runtime.commandlayer.eth
17+
ENS_PUBKEY_TEXT_KEY=cl.receipt.pubkey.pem
18+
19+
# Schema host (default: https://www.commandlayer.org)
20+
SCHEMA_HOST=https://www.commandlayer.org
21+
22+
# Schema verification mode:
23+
# false (default) = fetch+compile on demand with cache
24+
# true = only use pre-warmed validators; return 202 if not warmed
25+
VERIFY_SCHEMA_CACHED_ONLY=false
26+
27+
# Enable /debug/* endpoints (unset = 404)
28+
# ENABLE_DEBUG=1
29+
# DEBUG_TOKEN=changeme
30+
31+
# Idempotency cache TTL in ms (default: 60000)
32+
IDEMPOTENCY_TTL_MS=60000
33+
34+
# SSRF: comma-separated additional allowed hostnames for fetch verb
35+
# ALLOW_FETCH_HOSTS=trusted-api.example.com

.github/workflows/ci.yml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: ci
2+
3+
on:
4+
push:
5+
branches: ["**"]
6+
pull_request:
7+
8+
jobs:
9+
test:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- uses: actions/setup-node@v4
15+
with:
16+
node-version: "20"
17+
cache: "npm"
18+
19+
- name: Install dependencies
20+
run: npm ci
21+
22+
- name: Type check
23+
run: npm run lint
24+
25+
- name: Build
26+
run: npm run build
27+
28+
- name: Test
29+
run: npm test

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
node_modules/
2+
dist/
3+
.env
4+
.DS_Store
5+
*.log
6+
run-logs/

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Changelog
2+
3+
## 0.1.0
4+
5+
Initial implementation:
6+
7+
- `POST /run/v1.0.0` with explicit plan and scored router modes
8+
- 10 Commons verbs: fetch, describe, format, clean, parse, summarize, convert, explain, analyze, classify
9+
- Deterministic score function (no LLM): relevance + need_bonus + novelty + cost_penalty + risk_penalty
10+
- Prerequisite graph: fetch→clean→summarize→classify→parse→analyze→format (state-gated)
11+
- Schema-shaped request builders per verb (fetch special: x402+source only)
12+
- Append-only state model: `RunState` with artifacts, trace, decisions
13+
- Ed25519 + SHA-256 + json.sorted_keys.v1 receipt signing/verification
14+
- ENS TXT pubkey resolution for `runtime.commandlayer.eth` (`?ens=1`)
15+
- Schema validation via AJV compileAsync with background warm queue (`/debug/prewarm → 202`)
16+
- `/verify?schema=1`: cached-only mode returns 202 + retry_after_ms when not warmed
17+
- SSRF guard for fetch: blocks private IPs, localhost, IPv6, metadata addresses
18+
- Idempotency cache: SHA-256 key derivation from stable stringify; TTL configurable
19+
- NDJSON replay logs per run in `RUN_LOG_DIR`; `/replay/:run_id` endpoint
20+
- HTTP delegate mode: `RUNTIME_URL``RuntimeClient` per step
21+
- Local reference handlers (demo/test; no HTTP)
22+
- CLI: `cl-router run --goal ... --content/source/plan`
23+
- Debug endpoints gated by `ENABLE_DEBUG` env
24+
- ENS anchors embedded as constants: `ENS_RUNTIME_SIGNER`, `ENS_CLEANAGENT_EXAMPLE`
25+
- Tests: scoring, prereqs, requestBuilders, idempotency, engine
26+
- CI: lint + build + test
27+
- Docs: SPEC, API, CONTRACTS, INTEGRATION_RUNTIME, INTEGRATION_SITE, EXAMPLES

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) CommandLayer
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 163 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,163 @@
1-
# router
1+
# CommandLayer Router
2+
3+
Deterministic router runtime for the **CommandLayer Protocol Commons** (10 universal verbs).
4+
5+
## What it does
6+
7+
- `POST /run/v1.0.0` — executes Commons verbs via:
8+
- **explicit plan mode** (caller supplies ordered steps with conditions)
9+
- **scored mode** (deterministic scoring function; **no LLM**)
10+
- Builds **schema-shaped** Commons requests (`fetch` is special)
11+
- Produces **signed receipts per step** (Ed25519 + SHA-256 + sorted keys v1)
12+
- `POST /verify` — verifies receipts (optional ENS pubkey + schema validation)
13+
- AJV schema warm queue (non-blocking)
14+
- Idempotency cache (SHA-256 key derivation)
15+
- NDJSON replay logs per run
16+
- SSRF guard for fetch verb
17+
- CLI: `cl-router`
18+
19+
## Commons Verbs (10 Universal)
20+
21+
```
22+
fetch describe format clean parse
23+
summarize convert explain analyze classify
24+
```
25+
26+
## Quickstart
27+
28+
```bash
29+
npm install
30+
npm run build
31+
npm test
32+
npm start
33+
```
34+
35+
Server starts on `http://localhost:8080`.
36+
37+
## CLI
38+
39+
```bash
40+
# Scored mode
41+
node dist/cli/cl-router.js run --goal "summarize this" --content "Hello world"
42+
43+
# With URL source
44+
node dist/cli/cl-router.js run --goal "fetch and summarize" --source https://example.com
45+
46+
# Explicit plan from JSON file
47+
node dist/cli/cl-router.js run --plan my-plan.json
48+
```
49+
50+
## HTTP Delegate Mode
51+
52+
Set `RUNTIME_URL` to delegate step execution to the CommandLayer runtime:
53+
54+
```bash
55+
RUNTIME_URL=https://runtime.commandlayer.org npm start
56+
```
57+
58+
Without `RUNTIME_URL`, the router uses local reference handlers (demo/test).
59+
60+
## Endpoints
61+
62+
| Method | Path | Description |
63+
|---|---|---|
64+
| `GET` | `/health` | Health check |
65+
| `POST` | `/run/v1.0.0` | Execute a run |
66+
| `POST` | `/verify` | Verify a signed receipt |
67+
| `GET` | `/replay/:run_id` | Retrieve run event log |
68+
| `POST` | `/debug/prewarm` | Warm schema validators (requires ENABLE_DEBUG) |
69+
| `GET` | `/debug/validators` | Show AJV cache state (requires ENABLE_DEBUG) |
70+
71+
## ENS Anchors (Source of Truth)
72+
73+
### `runtime.commandlayer.eth` — Receipt Signer Identity
74+
75+
```
76+
cl.receipt.pubkey.pem = "-----BEGIN PUBLIC KEY-----\nMCowBQYDK2VwAyEA7Vkkmt6R02Iltp/+i3D5mraZyvLjfuTSVB33KwfzQC8=\n-----END PUBLIC KEY-----"
77+
cl.sig.kid = "v1"
78+
cl.sig.pub = "ed25519:CEHI9g4v8qMx8TLlbLVW7RtiCmzRF7U7gpkrp0iB/a0="
79+
cl.sig.canonical = "json.sorted_keys.v1"
80+
cl.receipt.signer = "runtime.commandlayer.eth"
81+
```
82+
83+
### `cleanagent.eth` — Canonical Commons Agent TXT Shape
84+
85+
```
86+
cl.verb = "clean"
87+
cl.version = "1.0.0"
88+
cl.class = "commons"
89+
cl.entry = "x402://cleanagent.eth/clean/v1.0.0"
90+
cl.receipt.signer = "runtime.commandlayer.eth"
91+
eth = "0xED976cA9036bC2d4E25BA8219faDA1Be503a09C7"
92+
```
93+
94+
## Environment Variables
95+
96+
```bash
97+
PORT=8080
98+
RUNTIME_URL=https://runtime.commandlayer.org # HTTP delegate mode
99+
RUN_LOG_DIR=run-logs # NDJSON replay log dir
100+
RECEIPT_SIGNING_PRIVATE_KEY_PEM=... # Ed25519 private key PEM
101+
ETH_RPC_URL=... # For ENS resolution (?ens=1)
102+
VERIFIER_ENS_NAME=runtime.commandlayer.eth
103+
SCHEMA_HOST=https://www.commandlayer.org
104+
VERIFY_SCHEMA_CACHED_ONLY=false
105+
ENABLE_DEBUG=1 # Enable /debug/* endpoints
106+
DEBUG_TOKEN=changeme
107+
IDEMPOTENCY_TTL_MS=60000
108+
ALLOW_FETCH_HOSTS=trusted-api.example.com # SSRF bypass list
109+
```
110+
111+
See `.env.example` for full reference.
112+
113+
## Docs
114+
115+
- [docs/SPEC.md](docs/SPEC.md) — Full `/run/v1.0.0` specification
116+
- [docs/API.md](docs/API.md) — API reference
117+
- [docs/CONTRACTS.md](docs/CONTRACTS.md) — RunRequest/RunResponse + receipt expectations
118+
- [docs/INTEGRATION_RUNTIME.md](docs/INTEGRATION_RUNTIME.md) — Runtime integration guide
119+
- [docs/INTEGRATION_SITE.md](docs/INTEGRATION_SITE.md) — Site docs updates
120+
- [docs/EXAMPLES.md](docs/EXAMPLES.md) — Usage examples
121+
122+
## Architecture
123+
124+
```
125+
src/
126+
server.ts Express server + route registration
127+
index.ts Public API exports
128+
router/
129+
commonsVerbs.ts 10-verb list
130+
policy.ts allow/deny verb policy
131+
prereqs.ts Prerequisite graph (deterministic)
132+
scoring.ts Score function + verb selector
133+
state.ts RunState helpers (append-only)
134+
requestBuilders.ts Schema-shaped request builders per verb
135+
applyReceipt.ts Receipt → artifact mapping
136+
stop.ts Global stop condition
137+
engine.ts Main run loop (explicit + scored)
138+
schemas/
139+
urls.ts Schema URL builders
140+
ajv.ts AJV instance + validator cache
141+
warm.ts Background warm queue
142+
receipts/
143+
sign.ts Ed25519 sign + verify
144+
verify.ts /verify endpoint handler
145+
ens.ts ENS TXT pubkey resolver
146+
security/
147+
ssrf.ts SSRF guard for fetch
148+
logging/
149+
replay.ts NDJSON event logger
150+
idempotency/
151+
cache.ts In-memory idempotency cache
152+
client/
153+
runtimeClient.ts HTTP client for runtime delegate
154+
cli/
155+
cl-router.ts CLI entrypoint
156+
types/
157+
run.ts RunRequest/RunResponse/RunState types
158+
commons.ts CommonsVerb type + ENS anchor constants
159+
```
160+
161+
## License
162+
163+
MIT

0 commit comments

Comments
 (0)