Skip to content

Commit cd29fb4

Browse files
committed
Runtime: signer env standardization + ENS verify smoke
1 parent 3fd2e4f commit cd29fb4

File tree

10 files changed

+497
-0
lines changed

10 files changed

+497
-0
lines changed

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,15 @@ clean_receipt.json
1414
tmp.*.json
1515
payload.json
1616

17+
18+
# --- secrets / key material ---
19+
*.pem
20+
*.key
21+
*_b64.txt
22+
private_key*
23+
public_key*
24+
*.der
25+
26+
# --- backups ---
27+
*.bak
28+
*.prepatch.*

AGENTS.md

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# CommandLayer — AI Agent Manifest (AGENTS.md)
2+
3+
> This file governs how Codex (and compatible AI agents) behave in any CommandLayer repository.
4+
> Drop this file into the root of any repo you want governed.
5+
> The companion file `CLAUDE.md` carries the same rules for Claude Code — keep them in sync.
6+
7+
---
8+
9+
## Ecosystem Overview
10+
11+
CommandLayer is a layered protocol system. Understand these layers before touching anything:
12+
13+
| Layer | Repos | Purpose |
14+
|---|---|---|
15+
| 1 — Protocol Contracts | `protocol-commons`, `protocol-commercial` | Schemas, versions, receipt shapes |
16+
| 2 — Crypto Truth | `runtime-core` | Canonicalization + signing/verifying. Single source of truth |
17+
| 3 — Execution Runtimes | `runtime`, `commercial-runtime` | Deterministic verbs that emit receipts |
18+
| 4 — Routing | `router` | Stable entrypoint, health/readiness/version, forwards to runtimes |
19+
| 5 — Developer Surface | `sdk` | Typed clients + verification helpers |
20+
| 6 — Discovery | `agent-cards` | Discovery payloads |
21+
| Integration Root | `stack` | E2E tests, docker-compose, compatibility matrix |
22+
23+
**Do not blur these layers.** A change in `runtime` must not invent fields not in the protocol schema. A change in `sdk` must not embed verification logic that belongs in `runtime-core`.
24+
25+
---
26+
27+
## Hard Contracts (Never Break These)
28+
29+
- Endpoints MUST be versioned: `/{verb}/v{protocol_version}` (e.g. `/describe/v1.0.0`)
30+
- Receipts MUST verify via `runtime-core` — no custom verification logic elsewhere
31+
- Protocol schemas are the contract; runtimes must not invent fields unless the schema allows it
32+
- Health endpoints are required on all services:
33+
- Router: `GET /health`, `GET /ready`, `GET /version`
34+
- Runtimes: `GET /health`, `GET /version`
35+
36+
---
37+
38+
## Workflow Orchestration
39+
40+
### >>Plan First<<
41+
Always plan before writing code. Outline:
42+
1. What layer(s) are affected
43+
2. What contracts are touched
44+
3. What tests will verify the change
45+
4. What can break downstream
46+
47+
Do not begin implementation until the plan is confirmed.
48+
49+
### >>Subagent Strategy<<
50+
For tasks spanning multiple repos or layers, decompose per layer. Never carry cross-layer changes silently. Surface cross-repo impacts explicitly before acting.
51+
52+
### >>Self-Improvement Loop<<
53+
After completing a task, review what you changed and ask: *Did I introduce any layer blurring, contract deviation, or fragility?* If yes, fix it before committing.
54+
55+
### >>Verification Before Done<<
56+
A task is not done until:
57+
- [ ] The targeted layer's tests pass
58+
- [ ] Stack e2e (`./e2e.sh`) is green (or you've confirmed it's unaffected)
59+
- [ ] No hard contracts are broken
60+
- [ ] The changeset is minimal — no collateral edits
61+
62+
### >>Demand Elegance (Balanced)<<
63+
Prefer the simplest correct solution. Do not over-engineer. Three similar lines of code is better than a premature abstraction. Do not add features, fallbacks, or options that weren't asked for.
64+
65+
### >>Autonomous Bug Fixing<<
66+
When you encounter a bug in code you did not write, fix the root cause — do not paper over it with a workaround. If the root cause is in a different layer or repo, flag it explicitly rather than patching around it.
67+
68+
---
69+
70+
## Task Management
71+
72+
### >>Track Progress<<
73+
Use a task list for any work with 3+ steps. Mark tasks in progress before starting and completed immediately upon finishing. Never batch completions.
74+
75+
### >>Explain Changesets<<
76+
Every commit message must explain *why*, not just *what*. Reference the layer affected and the contract being upheld or changed. Format:
77+
78+
```
79+
[layer] short imperative description
80+
81+
Why: <one sentence on the reason>
82+
Contract impact: <none | describe if any>
83+
```
84+
85+
### >>Constant Revisits<<
86+
After each step, re-read the plan. Confirm you're still on the minimal path. Bail early if scope has crept.
87+
88+
### >>Capture Lessons<<
89+
If you discover something surprising about the codebase (hidden coupling, undocumented constraint, layer violation), add a note to `ARCHITECTURE.md` or the relevant `COMPATIBILITY_MATRIX.md` before finishing.
90+
91+
---
92+
93+
## Core Principles
94+
95+
### >>Simplicity First<<
96+
Every line added is a maintenance burden. Add only what the task requires. Do not refactor surrounding code unless it directly blocks the task.
97+
98+
### >>No Lazy Causes<<
99+
Do not work around a problem. Identify and fix the actual cause. If the cause is outside your scope, surface it to the user and stop.
100+
101+
### >>Minimal Impact<<
102+
Prefer changes that are local to one layer. If a change ripples into two or more layers, that is a signal to slow down, re-plan, and confirm with the user.
103+
104+
---
105+
106+
## Development Workflow
107+
108+
### Local Setup
109+
```bash
110+
cp .env.example .env
111+
./checkout-deps.sh # clones all dependent repos at correct refs
112+
./inject-dockerfiles.sh # only needed if dep repos lack Dockerfiles
113+
docker compose up -d --build
114+
./e2e.sh # must be green before any PR
115+
```
116+
117+
### What "Green" Means
118+
- Router is up and healthy
119+
- Runtimes respond
120+
- A request returns a structured receipt (or 402 if paywall enabled)
121+
- No HTML errors or junk responses
122+
123+
### Dependency Versions
124+
All repo refs are pinned in `REPO_LOCK.json`. Do not change a ref without understanding the compatibility matrix in `COMPATIBILITY_MATRIX.md`.
125+
126+
---
127+
128+
## Git Conventions
129+
130+
- Branch names for AI sessions: `claude/<task-slug>-<session-id>`
131+
- Commit to the designated branch — never push to `main` directly
132+
- Push with: `git push -u origin <branch-name>`
133+
134+
---
135+
136+
## What This File Is Not
137+
138+
This file does not replace per-repo README or inline code comments. It governs *agent behavior*, not user documentation. Keep it focused on rules and conventions — not tutorials.
139+
140+
---
141+
142+
*Sync any changes here into `CLAUDE.md` (Claude Code equivalent) to keep both agents governed by the same rules.*

CLAUDE.md

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
# CommandLayer — AI Agent Manifest (CLAUDE.md)
2+
3+
> This file governs how Claude Code (and compatible AI agents) behave in any CommandLayer repository.
4+
> Drop this file into the root of any repo you want governed.
5+
> The companion file `AGENTS.md` carries the same rules for Codex — keep them in sync.
6+
7+
---
8+
9+
## Ecosystem Overview
10+
11+
CommandLayer is a layered protocol system. Understand these layers before touching anything:
12+
13+
| Layer | Repos | Purpose |
14+
|---|---|---|
15+
| 1 — Protocol Contracts | `protocol-commons`, `protocol-commercial` | Schemas, versions, receipt shapes |
16+
| 2 — Crypto Truth | `runtime-core` | Canonicalization + signing/verifying. Single source of truth |
17+
| 3 — Execution Runtimes | `runtime`, `commercial-runtime` | Deterministic verbs that emit receipts |
18+
| 4 — Routing | `router` | Stable entrypoint, health/readiness/version, forwards to runtimes |
19+
| 5 — Developer Surface | `sdk` | Typed clients + verification helpers |
20+
| 6 — Discovery | `agent-cards` | Discovery payloads |
21+
| Integration Root | `stack` | E2E tests, docker-compose, compatibility matrix |
22+
23+
**Do not blur these layers.** A change in `runtime` must not invent fields not in the protocol schema. A change in `sdk` must not embed verification logic that belongs in `runtime-core`.
24+
25+
---
26+
27+
## Hard Contracts (Never Break These)
28+
29+
- Endpoints MUST be versioned: `/{verb}/v{protocol_version}` (e.g. `/describe/v1.0.0`)
30+
- Receipts MUST verify via `runtime-core` — no custom verification logic elsewhere
31+
- Protocol schemas are the contract; runtimes must not invent fields unless the schema allows it
32+
- Health endpoints are required on all services:
33+
- Router: `GET /health`, `GET /ready`, `GET /version`
34+
- Runtimes: `GET /health`, `GET /version`
35+
36+
---
37+
38+
## Workflow Orchestration
39+
40+
### >>Plan First<<
41+
Always enter plan mode before writing code. Outline:
42+
1. What layer(s) are affected
43+
2. What contracts are touched
44+
3. What tests will verify the change
45+
4. What can break downstream
46+
47+
Do not begin implementation until the plan is confirmed.
48+
49+
### >>Subagent Strategy<<
50+
For tasks spanning multiple repos or layers, decompose into subagents per layer. Never let a single agent context carry cross-layer changes silently. Surface cross-repo impacts explicitly before acting.
51+
52+
### >>Self-Improvement Loop<<
53+
After completing a task, review what you changed and ask: *Did I introduce any layer blurring, contract deviation, or fragility?* If yes, fix it before committing.
54+
55+
### >>Verification Before Done<<
56+
A task is not done until:
57+
- [ ] The targeted layer's tests pass
58+
- [ ] Stack e2e (`./e2e.sh`) is green (or you've confirmed it's unaffected)
59+
- [ ] No hard contracts are broken
60+
- [ ] The changeset is minimal — no collateral edits
61+
62+
### >>Demand Elegance (Balanced)<<
63+
Prefer the simplest correct solution. Do not over-engineer. Three similar lines of code is better than a premature abstraction. Do not add features, fallbacks, or options that weren't asked for.
64+
65+
### >>Autonomous Bug Fixing<<
66+
When you encounter a bug in code you did not write, fix the root cause — do not paper over it with a workaround. If the root cause is in a different layer or repo, flag it explicitly rather than patching around it.
67+
68+
---
69+
70+
## Task Management
71+
72+
### >>Track Progress<<
73+
Use a task list for any work with 3+ steps. Mark tasks `in_progress` before starting and `completed` immediately upon finishing. Never batch completions.
74+
75+
### >>Explain Changesets<<
76+
Every commit message must explain *why*, not just *what*. Reference the layer affected and the contract being upheld or changed. Format:
77+
78+
```
79+
[layer] short imperative description
80+
81+
Why: <one sentence on the reason>
82+
Contract impact: <none | describe if any>
83+
```
84+
85+
### >>Constant Revisits<<
86+
After each step, re-read the plan. Confirm you're still on the minimal path. Bail early if scope has crept.
87+
88+
### >>Capture Lessons<<
89+
If you discover something surprising about the codebase (hidden coupling, undocumented constraint, layer violation), add a note to `ARCHITECTURE.md` or the relevant `COMPATIBILITY_MATRIX.md` before finishing.
90+
91+
---
92+
93+
## Core Principles
94+
95+
### >>Simplicity First<<
96+
Every line added is a maintenance burden. Add only what the task requires. Do not refactor surrounding code unless it directly blocks the task.
97+
98+
### >>No Lazy Causes<<
99+
Do not work around a problem. Identify and fix the actual cause. If the cause is outside your scope, surface it to the user and stop.
100+
101+
### >>Minimal Impact<<
102+
Prefer changes that are local to one layer. If a change ripples into two or more layers, that is a signal to slow down, re-plan, and confirm with the user.
103+
104+
---
105+
106+
## Development Workflow
107+
108+
### Local Setup
109+
```bash
110+
cp .env.example .env
111+
./checkout-deps.sh # clones all dependent repos at correct refs
112+
./inject-dockerfiles.sh # only needed if dep repos lack Dockerfiles
113+
docker compose up -d --build
114+
./e2e.sh # must be green before any PR
115+
```
116+
117+
### What "Green" Means
118+
- Router is up and healthy
119+
- Runtimes respond
120+
- A request returns a structured receipt (or 402 if paywall enabled)
121+
- No HTML errors or junk responses
122+
123+
### Dependency Versions
124+
All repo refs are pinned in `REPO_LOCK.json`. Do not change a ref without understanding the compatibility matrix in `COMPATIBILITY_MATRIX.md`.
125+
126+
---
127+
128+
## Git Conventions
129+
130+
- Branch names for AI sessions: `claude/<task-slug>-<session-id>`
131+
- Commit to the designated branch — never push to `main` directly
132+
- Push with: `git push -u origin <branch-name>`
133+
- On network failure: retry up to 4 times with exponential backoff (2s, 4s, 8s, 16s)
134+
135+
---
136+
137+
## What This File Is Not
138+
139+
This file does not replace per-repo README or inline code comments. It governs *agent behavior*, not user documentation. Keep it focused on rules and conventions — not tutorials.
140+
141+
---
142+
143+
*Sync any changes here into `AGENTS.md` (Codex equivalent) to keep both agents governed by the same rules.*

gen-ed25519.mjs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import crypto from "crypto";
2+
3+
const { publicKey, privateKey } = crypto.generateKeyPairSync("ed25519");
4+
5+
// Private key (PKCS8 PEM) for signing
6+
const privPem = privateKey.export({ format: "pem", type: "pkcs8" });
7+
8+
// Public key as raw 32-byte base64 (matches ENS cl.sig.pub format after "ed25519:")
9+
const pubSpkiDer = publicKey.export({ format: "der", type: "spki" });
10+
const raw32 = Buffer.from(pubSpkiDer).subarray(pubSpkiDer.length - 32);
11+
if (raw32.length !== 32) throw new Error("Unexpected public key length");
12+
const pubB64 = raw32.toString("base64");
13+
14+
console.log("CL_PRIVATE_KEY_PEM=\n" + privPem.trim());
15+
console.log("CL_PUBLIC_KEY_B64=" + pubB64);

scripts/dev.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
PORT="${PORT:-8099}"
5+
HOST="${HOST:-127.0.0.1}"
6+
7+
# generate keys if missing
8+
if [ ! -s ./keys.env ]; then
9+
node tools/mkkeys.mjs
10+
fi
11+
12+
source ./keys.env
13+
14+
ENABLE_DEBUG=1 DEBUG_TOKEN=smoke \
15+
HOST="$HOST" PORT="$PORT" \
16+
ETH_RPC_URL="${ETH_RPC_URL:-}" \
17+
CL_RECEIPT_SIGNER="runtime.commandlayer.eth" \
18+
CL_KEY_ID="v1" \
19+
CL_CANONICAL_ID="json.sorted_keys.v1" \
20+
node server.mjs

0 commit comments

Comments
 (0)