The chokepoint position the AI-gateway field occupies (LiteLLM, Bifrost, Portkey), rebuilt on the two axes nobody there holds: the unit of account is the joule, and the audit is a hash-chained cryptographic receipt log rather than a dollar figure and an OpenTelemetry span. jcp-runtime gains two-phase metered enforcement. A metered gateway cannot know a call's cost until it runs, so `decide` (check + debit a known cost) splits: `authorize` runs every validity check and gates on "any budget remains" without debiting; `charge` debits the MEASURED cost afterward, saturating at the ceiling so the final call's overrun is recorded (budget_remaining 0, cost > debited) rather than hidden. jcp-receipt gains ReceiptLog: an append-only, hash-chained log where each entry's signed core commits to the prior entry's envelope content id (genesis links to an all-zero sentinel). verify_log walks the chain end to end; excising, reordering, or splicing a receipt breaks it at that index — the integrity layer OTel lacks and the property the EU AI Act logging obligations and the notarized-agents research both reach for. Allows and denies are both chained. jcp-gateway: the gateway crate + stdio binary. relay() classifies each client message, passes through non-tools/call traffic, and turns every tools/call into an enforcement point: authorize → meter the upstream call on real hardware (sandbox-meter: IOReport/RAPL/NVML) → debit measured joules → seal into the chain. A denied call never reaches the server. The Upstream trait keeps policy testable without a subprocess. Live, in front of a subprocess MCP server: read_file calls allowed and debited (827,000 and 834,825 µJ measured on Apple Silicon), a shell/`rm -rf /` call DENIED before reaching the server, three sealed receipts (allow/deny/allow) in a chain that verifies. 69 jcp tests (gateway: allow/deny/budget-exhaustion+chain-verify; receipt: tamper-evidence via excise+reorder), clippy zero. Co-Authored-By: Claude Fable 5 <[email protected]>
41 lines
985 B
TOML
41 lines
985 B
TOML
[workspace]
|
|
resolver = "2"
|
|
members = [
|
|
"crates/jcp-schema",
|
|
"crates/jcp-grant",
|
|
"crates/jcp-runtime",
|
|
"crates/jcp-receipt",
|
|
"crates/jcp-bridge",
|
|
"crates/jcp-energy",
|
|
"crates/jcp-wire",
|
|
"crates/jcp-threshold",
|
|
"crates/jcp-channel",
|
|
"crates/jcp-conformance",
|
|
"crates/jcp-cli",
|
|
"crates/jcp-gateway",
|
|
]
|
|
|
|
[workspace.package]
|
|
version = "0.1.0"
|
|
edition = "2021"
|
|
license = "Apache-2.0"
|
|
repository = "https://github.com/transaction-science/open-standards"
|
|
rust-version = "1.85"
|
|
|
|
[workspace.dependencies]
|
|
jcp-schema = { path = "crates/jcp-schema" }
|
|
jcp-grant = { path = "crates/jcp-grant" }
|
|
jcp-runtime = { path = "crates/jcp-runtime" }
|
|
jcp-receipt = { path = "crates/jcp-receipt" }
|
|
jcp-energy = { path = "crates/jcp-energy" }
|
|
|
|
blake3 = "1"
|
|
ed25519-dalek = { version = "2", features = ["rand_core"] }
|
|
bs58 = "0.5"
|
|
serde = { version = "1", features = ["derive"] }
|
|
serde_json = "1"
|
|
hex = "0.4"
|
|
thiserror = "2"
|
|
|
|
[workspace.lints.clippy]
|
|
all = "warn"
|