open-standards/sandbox
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science f1b662078b
All checks were successful
energy meters on real hardware / RAPL and NVML on jetson-hub (pull_request) Successful in 33s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 4m1s
standards workspaces build + test / aac-rs (pull_request) Successful in 2m33s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 2m27s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 1m7s
standards workspaces build + test / map-rs (pull_request) Successful in 50s
standards workspaces build + test / mesh-rs (pull_request) Successful in 40s
standards workspaces build + test / openpay (pull_request) Successful in 3m5s
standards workspaces build + test / arl-rs (pull_request) Successful in 1m10s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m55s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m28s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 1m8s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 1m9s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m29s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m14s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m11s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m39s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 3m2s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 6m58s
energy tests: the load-sensitive tick floor in proof-cascade and sandbox-meter
#166 fixed this class of defect in `eoc-meter` and `jouleclaw-energy`: an
energy-probe test asserting a floor on thread CPU per tick, which the host's
scheduler controls, failing on the dev Mac because the dev Mac is also the
macOS runner. The same code exists in two more crates, and the same assertion
with it. CI surfaced `proof-cascade` by failing an unrelated PR; sweeping for
the pattern found `sandbox-meter` as well, rather than waiting for another
round.

A tick spins until the thread's CPU clock advances 25 ms **or** a 500 ms wall
cap passes. Both copies carried a comment asserting the opposite — "the tick
burns thread CPU time, so host load does not shorten it; only its wall-clock cap
can" — a sentence containing its own refutation, since the cap is how load
shortens a tick.

The two outcomes that matter are not separable by time: a spin the host starved
into the cap and a tick that simply slept both show a long wall span against
little CPU. I tried a per-turn CPU floor first, reasoning that a turn is fixed
work so starvation lowers turns-per-second rather than the cost of a turn.
Measuring refuted it: a turn that sleeps 1 ms costs 13.3-15.8 µs of thread CPU
against a real turn's 2.13-2.92 µs, because a blocking body's context switch is
charged to the thread. Even the direction was wrong.

So each tick reports what it did. `spin_tick` / `spin_for` return a
`TickOutcome` — the CPU it saw itself burn, and how many turns of the spin loop
it ran — and each probe collects one per tick, alongside the interval's wall
span beside its CPU span. Per tick: the loop ran at all (a tick that never span
did not burn CPU, at any load), and the tick stopped for one of its two stated
reasons rather than early. The gaps measured by the tests' own clocks still
bound it from above and keep CPU under wall.

- **proof-cascade**: three load-sensitive sites — `assert_sampling`'s
  per-interval floor, an aggregate floor over a whole scripted call, and a
  per-interval floor in the live-rail test. `ProbeRun` gains `interval_wall` and
  the per-tick outcomes; `burn_thread_cpu` reports the CPU it was already
  computing.
- **sandbox-meter**: the per-interval `PROBE_TICK / 2` floor. This crate already
  had `assert_tick` using the either-condition rule for the tick itself, so the
  interval check now matches the crate's own convention — and both are stronger
  for the spin count, since that rule alone admits a tick that slept through its
  cap. `TickOutcome` becomes public because it already appears in a public
  signature: `RaplPackages::live_in` and `counter_liveness` take a tick that
  returns it, so `sandbox-exec-microvm` has to name it and build one.

Where a scripted tick stands in for the burn — fake powercap trees, the MSR
fakes, the hardware test's own oracle — it reports a turn, with a comment saying
that this is the test declaring a real spin ran and not a figure chosen to clear
a threshold. The hardware test's tick keeps using `oracle::burn`, so the oracle
stays independent of what it checks.

Three doc comments asserting "a tick burns a full tick however loaded the
machine is" are corrected in place; leaving that beside a fixed assertion would
reinvite the mistake.

Two call sites are `cfg(target_os = "linux")` and invisible to every run on this
host: `sandbox-meter/tests/rapl_hardware.rs`, which CI's jetson-hub job caught,
and `probe::counter_liveness_tick`, reached on the Linux side through
`MsrRaplMeter::host`, which `cargo check --target aarch64-unknown-linux-gnu
--all-targets` caught. That check is a weak oracle — it runs nothing — but it is
the right shape for a type mismatch in code the host never compiles.
`CARGO_FEATURE_NO_NEON=1` is needed, or blake3's build script wants Linux C
headers. The whole sandbox workspace cannot cross-check (`zstd-sys` needs a real
cross compiler), so instead I confirmed that nothing outside these crates
references the changed entry points, which makes the per-crate checks exhaustive
for callers.

Falsified in both crates: a tick that sleeps instead of spinning, and a tick
skipped entirely. One sleep falsification first looked like a pass and was a
compile error — checked, not assumed. In proof-cascade a tick cut short of both
stopping conditions is caught too.

Verified: proof-rs 139 passed, sandbox-rs 324 passed, and the five touched
crates check clean for aarch64-unknown-linux-gnu. The two clippy warnings in
proof-cascade are in untouched code, the same pair that predates the change in
eoc-meter — these files are copies of one another, which is why the defect was
in four places.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-10-07 10:03:30 -04:00
..
conformance Sandbox + JCP: long-horizon agent execution 2026-06-12 23:14:59 -04:00
proof Add aac, map, sandbox standards; catalog the standards family 2026-06-07 17:04:36 -04:00
sandbox-rs energy tests: the load-sensitive tick floor in proof-cascade and sandbox-meter 2026-10-07 10:03:30 -04:00
spec sandbox: let an S1-S5 attestation say how it confined the run (SPEC §7.9) 2026-08-24 23:58:46 -04:00
CONTRIBUTING.md Add aac, map, sandbox standards; catalog the standards family 2026-06-07 17:04:36 -04:00
LICENSE Add aac, map, sandbox standards; catalog the standards family 2026-06-07 17:04:36 -04:00
LICENSE-SPEC Add aac, map, sandbox standards; catalog the standards family 2026-06-07 17:04:36 -04:00
README.md sandbox-meter: this process's own CPU energy, read only for in-process work and only while it keeps advancing 2026-09-30 23:01:05 -04:00
SECURITY.md Add aac, map, sandbox standards; catalog the standards family 2026-06-07 17:04:36 -04:00
SPEC.md sandbox: give the S7 locality claim something that can falsify it (SPEC §7.7) 2026-08-26 11:52:33 -04:00

Sandbox

A sandbox for the heterogeneous compute fabric. Isolate, capability-gate, meter, and attest — owned by no one.

Sandbox is the isolated-execution substrate of the Transaction Science open standards. Where Smart Byte carries value, EOC carries compute, and Joule Code carries coding work, Sandbox carries the place those operations run: a bounded environment in which an untrusted unit of work executes, sees only what it was granted, and leaves behind a signed account of what it did and what it cost.

Every other sandbox in the field isolates a CPU process — a container, a microVM, a Linux process pinned to a core. The accelerator, where present, is an opaque passthrough that nobody meters and nobody attests. But agentic and AI work does not run on a CPU. It runs across a fabric — CPU, GPU, NPU, TPU, photonic, quantum. So in this standard the unit of isolation is not a process; it is a heterogeneous unit of work, and the accelerator is a first-class citizen of the isolation boundary: a capability you grant, a resource you meter in joules, and a line item you attest.

A Sandbox run carries exactly four guarantees: isolation (the unit runs at the lowest tier of an eight-rung ladder, S0–S7, that satisfies its needs, and cannot reach past it), capability (every resource the unit touches — each device class included — was explicitly granted; ungranted access is denied), metering (the run emits a signed energy receipt with per-device-class joule attribution and an honest provenance tag on every reading — and the reference meter reads vendor energy counters: Apple Silicon's energy model via IOReport, Intel/AMD RAPL via powercap, NVIDIA's total-energy counter via NVML. A reading is tagged HwShunt only while its counter is demonstrably live: each vendor counter is used only if every rail of it that the meter sums into one figure keeps advancing while the meter's probe burns CPU — in at least 5 sample intervals, at least 4 of every 5, over at least 300 ms — every IOReport CPU energy rail (the rail itself, one per die on a multi-die part), every RAPL package and every NVML GPU; and a span across which the CPU counter held is never a reading. A counter that is absent, or present but not live — frozen, or republished in lumps, as the IOReport CPU rails are on macOS 27 — yields no hardware-graded figure: the span degrades to the labeled Estimator (wall-clock × TDP), never a fabricated measurement, and ioreport_status(), rapl_status() and nvml_status() say why a host is estimated. For work on the meter's own process there is one more source, kept out of the default meter: on macOS, the CPU energy the kernel attributes to the process's own threads (proc_pid_rusage), read through PowerMeter::detect_in_process() under the same liveness rule — never for a subprocess, which it does not cover; a single-process child's own figure is read from the exited child instead. Because a live counter reports the whole SoC, the meter can attribute it to a single process tree by CPU-time apportionment — tagged ModelBased, since the reading is a measurement but the split is a model), and attestation (a signed statement of what image ran, at what tier, under what grants, on what hardware, for what cost, with a deterministic-replay journal hash where one was produced).

The substrate is intentionally ownerless: no protocol-level token, permissive licensing on spec text and reference code, and conformance vectors so any implementer can verify canonicity without a trust relationship with the authors. A conforming host runs a unit, enforces its grants, meters its energy, and seals its attestation without contacting any single steward's servers as a condition of operation. Transaction Science is one steward: it publishes the spec, ships a reference implementation, and operates commercial services around the substrate — not its proprietor.

The doctrine

Isolation per joule, across the whole fabric. The durable layer of a sandbox is not fast container boot or a managed control plane — both are commoditized. It is the boundary itself, made honest: the lowest isolation tier that satisfies the work, every resource gated by an explicit capability, and a signed receipt that attributes energy to each device class it touched. "Run it safely" and "don't waste energy" are the same optimization: an over-isolated run burns joules it did not need, and an unmetered accelerator is exactly where the energy hides.

Three consequences, normative in SPEC.md:

  1. The ladder. A host MUST run a unit at the lowest isolation tier of S0:Bare → S1:Capability → S2:Sandbox → S3:Partition → S4:Unikernel → S5:MicroVM → S6:Confidential → S7:Sovereign that satisfies the unit's capability set, and MUST NOT escalate beyond what the grants require. Escalation is the escape hatch, not the entry point — the same discipline the cascade applies to inference, applied to isolation.
  2. The grant. Every resource a unit can touch — network, storage, key-value, and each compute device class (Cpu | Simd | Gpu | Npu | Tpu | Lpu | Photonic | Quantum) — MUST be explicitly granted. Access to an ungranted resource MUST be denied. Each compute grant carries a joule budget.
  3. The attested receipt. Every completed run MUST emit an energy receipt accounting joules per device class — measured + estimated, integer microjoules — each reading tagged HwShunt | ModelBased | Estimator, sealed as a JCR-1 envelope; and MUST emit an attestation binding the unit, image, tier, grants, hardware, and receipt, signed Ed25519 over JCS-canonicalized JSON — the same attestation primitive the ARL Sandbox (ARL-S) uses, so the two interoperate at the attestation layer.

Contents

  • SPEC.md — the normative specification (RFC 2119): the unit of work, the S0–S7 isolation ladder, the capability-grant model, the per-device energy receipt, the attestation, and the conformance contract.
  • spec/ — sub-specifications: tiers.md (the ladder), capabilities.md (the grant model), receipts.md (per-device energy), attestation.md (the signed claim + replay journal), conformance.md (test obligations).
  • conformance/ — signed wire vectors. An implementation is conformant if it round-trips these.
  • proof/ — the proof matrix: a ledger of signed proof cells, each a real run of the conformance pack + a sealed workload on a real target (substrate × OS × arch × cloud × hardware × tier). A green cell is a signature over a real run, not a claim.
  • sandbox-rs/ — the Rust reference library: content addressing and tiers (sandbox-schema), the capability model and deny-by-default enforcer (sandbox-capability), the per-device receipt and JCR-1 sealing (sandbox-meter), the attestation and replay journal (sandbox-attest), the reference host — tier minimization plus sealed-run assembly (sandbox-runtime), a real S2 (WASM) executor on wasmtime with fuel→joule metering and a brokered, Enforcer-gated host-call surface that journals every nondeterministic input for replay (sandbox-exec-wasm), a real S5 (microVM) executor driving Firecracker — both an API-socket driver and a supervised-child lifecycle driver — with pluggable per-device power metering (sandbox-exec-microvm), the S6 confidential-tier TEE layer — SEV-SNP report model, policy + real ECDSA-P384/SHA-384 verification, and a configfs-tsm hardware provider with a software-grounded test provider (sandbox-tee), the conformance harness with the gen_vectors generator (sandbox-conformance), the proof-matrix harness that runs the pack + a sealed run on a target and emits a signed proof cell (sandbox-proof), the sandbox reference checker/runner (sandbox-cli), and the JCP gate (sandbox-jcp) — execution as a JCP consumer: a metered Grant bound to the unit's image by content address is decided by the JCP runtime before the executor is ever invoked, the declared energy ceiling is debited from the delegation chain pre-run, and the decision (allow and deny alike) seals as a JCR-1 receipt alongside the sandbox's own sealed run.

Heterogeneity is normative, not an extension

The clause that distinguishes this standard from a process sandbox is in SPEC.md §2.3 and §6.2: where a unit is granted an accelerator capability, a conforming host MUST attribute energy to that device class separately in the receipt, MUST record the device identity (class, model, driver) in the attestation, and at tiers S5 and above MUST report the measurement provenance honestly (HwShunt where the device exposes a live energy interface — NVML, RAPL, ROCm SMI, Level Zero — ModelBased or Estimator otherwise). A host that runs accelerated work but reports a single undifferentiated CPU energy figure is not conformant.

Lineage

Sandbox draws its design from two Transaction Science runtimes and generalizes a third standard:

  • The isolation ladder and the capability-grant model follow the layered, hardware-rooted isolation and the per-resource grant set proven in the invisible-infrastructure runtime — capabilities first, WASM and microVM tiers above, TEE and sovereign tiers at the top, accelerators as explicit device capabilities throughout.
  • The per-device energy receipt and its provenance discipline follow the picojoule receipt and measurement-quality model of the JouleDB substrate, sealed in the family's shared JCR-1 envelope.
  • The attestation generalizes the SUT / Harness / Supervisor separation and the signed-telemetry model of the ARL Sandbox out of a measurement-only role into a standalone substrate that ARL-S, JouleClaw, EOC, and Joule Code can target instead of each re-specifying isolation.

Status

v0.1.0 draft. Specification core published (the unit, the ladder, the grant model, the per-device receipt, the attestation); the reference library lands the schema, capability, meter, attest, runtime, and conformance crates with the sandbox CLI, plus two real tier executors: a wasmtime-backed S2 executor that runs untrusted WASM under fuel and memory caps, meters fuel→joules, and brokers every capability the guest exercises (kv, clock, randomness) through the deny-by-default Enforcer — journaling each nondeterministic input so the run's attestation carries a replay-journal root; and a Firecracker-driver S5 executor that boots a microVM (API-socket or supervised-child lifecycle) and meters CPU and an assigned accelerator separately through pluggable power meters (RAPL/NVML-class, with an honest ModelBased fallback). Energy receipts seal as JCR-1 envelopes (canonical det-CBOR + COSE_Sign1, EdDSA), the signed-receipt format shared across the family; attestations sign Ed25519 over JCS-canonicalized JSON, interoperable with ARL-S. The conformance vectors in conformance/v1/ are real, cryptographically computed values — including a committed pack of adversarial negatives a conformant host must reject — regenerated by gen_vectors and verified by the harness (in-code and file-backed).

Readiness is classified per component (Solid / Engineering / Research / Theory) in SPEC.md §9 and respected when sequencing work. The S2 (WASM) executor runs and meters real guests; the S4–S5 (microVM) driver is real Firecracker integration (it boots a guest on Linux+KVM); and the S6/S7 confidential and sovereign tiers are implemented end-to-end — the host obtains a TEE report, verifies it (real ECDSA-P384/SHA-384 signature + measurement/TCB/debug/report-data policy), seals the evidence into the attestation, binds a locality, and links the run into a tamper-evident audit chain. The single honest caveat (SPEC §9): generating a genuine vendor-signed report requires the CPU's security processor — the configfs-tsm provider does so on real confidential hardware and reports Unavailable elsewhere, while a tagged software-grounded provider, which never claims a hardware root, covers wiring and tests.

  • ARL — the AI Readiness Level standard; its ARL Sandbox (ARL-S) is the measurement-specialized profile of this substrate. The attestation primitive (Ed25519 over JCS) is shared, so an ARL-S session attestation and a Sandbox run attestation verify under the same tooling.
  • JouleClaw — the energy-optimised AI runtime; a JouleClaw agent's tool execution runs inside a Sandbox, and the receipt provenance discipline (HwShunt | ModelBased | Estimator) and the JCR-1 envelope are JouleClaw's.
  • Joule Code — a coding operation that executes generated code (a test run, a build) runs that code inside a Sandbox; the joule receipt composes.
  • EOC — the energy-optimised compute substrate; the discipline of stopping at the cheapest tier that closes the request is EOC's, applied here to isolation tiers.

Licence

Reference code (everything under sandbox-rs/) is Apache-2.0 (LICENSE). Specification text (SPEC.md, spec/) is CC-BY-4.0 (LICENSE-SPEC). The wire format and the right to fork are public.