open-standards/sandbox/spec/build.md
Transaction Science ba1212361f Add aac, map, sandbox standards; catalog the standards family
Commit the previously-untracked standard directories and catalog them in the
root README alongside proof:

- aac/    — communication cargo class: portable boards + a ten-level
            offline-first cascade (Apache-2.0 code / CC-BY-4.0 spec).
- map/    — geospatial cargo class: range-requestable signed tilesets +
            an F0–F4 fidelity cascade (Apache-2.0 code / CC-BY-4.0 spec).
- sandbox/— isolated, metered, attested execution across the heterogeneous
            compute fabric (Apache-2.0 code / CC-BY-4.0 spec).
- jouleclaw-otel-authz, jouleclaw-trust — new jouleclaw reference crates.

Root README now lists aac, map, sandbox, and proof in the catalog, the tree,
and the contribution guide.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-07 17:04:36 -04:00

128 lines
6.6 KiB
Markdown

# The attested build loop
A coding agent does not take one action — it scaffolds, runs, tests, and fixes,
across many steps. Every other AI app-builder hands the user the resulting app
and nothing else: no record of *what the agent did, what it cost, or whether it
is safe*. This standard defines the missing artifact — a **build receipt**: a
signed, reproducible, metered account of a whole build, assembled from steps
that each ran inside the metered+attested sandbox.
## What a build is
A **build** is an ordered sequence of **steps**, each a unit run under explicit
grants (§5). Agent-generated code is untrusted, so each step minimizes to at
least **S2** (§2.3). Each step is executed via the host's run-and-seal path,
which binds the executor's tier to the grants and produces a sealed receipt, an
attestation, and a RATS EAT (§6, §7, §7.8).
## The build receipt
For each step the receipt records the content address of **exactly the unit that
ran** (`image_id`) and its grants (`grants_id`), the tier, the outcome, the
energy it cost (the JCR-1 receipt total, honestly tagged per device), the
attestation id, and the step's EAT. The builder **MUST** verify each step's
sealed receipt, attestation, and EAT before recording it — the build receipt
contains nothing unchecked.
The build's identity is content-addressed:
```
build_id = BLAKE3( intent ‖ image_id(step_1) ‖ … ‖ image_id(step_n) )
```
so an identical build is identical by address — the **lockfile for generation**
the category lacks. The receipt is then signed Ed25519 over its JCS-canonical
form (the family attestation primitive, §7.3), giving:
```
BuildReceipt {
profile: "sandbox.build/1",
build_id, intent, steps: [StepRecord],
total_energy_uj, tier_max, prev, host_id, at_unix_us
}
```
## Coding-op provenance
A step **MAY** carry the **coding op** it represents — the agent's edit: the
`path`, the content addresses of the file before and after, and the `author`
(the model or agent that produced it). The op is content-addressed (`op_id`) and
recorded in the step, so it is **signed into the build receipt**: the receipt
attests not just *what ran* but *what changed and what made it* — the code
lineage the category's "black box" lacks. The op is provenance, not execution
identity, so it does not affect `build_id` or the cache key.
## The build ledger
Build receipts chain into an append-only **build ledger**: each receipt's `prev`
is the previous build's `build_id` (the genesis id for the first). A verifier
walks the chain, checking every signature and every link — a tamper-evident
account of every build in order. The reference provides both an in-memory ledger
and a **durable, file-backed** one (`FileBuildLedger`) that persists the chain as
JSONL, re-verifies it on open, and refuses to load a tampered file;
`verify_ledger_file` (and the `sandbox-build verify` / MCP `verify_ledger`
surfaces) re-check a persisted ledger independently. This is the "verifiable
record of how the app came to be" that regulated use (and EU AI Act energy
disclosure) requires and that no incumbent produces.
## What it answers
- **Provenance** — a signed record of what ran, step by step, addressable and replayable.
- **Energy** — per-step and total joules, from the §6 receipts (SCI-aligned, consumer-side).
- **Reproducibility** — the build is pinned by content id; the same intent + steps reproduce the same `build_id`.
- **Isolation + safety** — every step ran under deny-by-default capabilities at the minimized tier; nothing executed outside the sandbox.
- **Portability** — the receipt and ledger travel with the artifact; ownership is the *account*, not just the files.
## Deterministic-first (the cascade)
A build resolves each step at the cheapest tier that closes it, and records
which tier did:
- **L0 — cache.** A step is content-addressed by `(image ‖ grants ‖ trusted)`.
Because a sandbox run is deterministic, an identical step yields an identical
result, so a prior attested result is reused with **no new execution and no
new energy** — provenance-as-cache.
- **L1 — deterministic execution.** Otherwise the step runs in the sandbox.
Execution *is* the verification; the result is attested and cached.
A frontier model is **never invoked inside the sandbox** — generation (the part
that needs a model) happens upstream in the agent surface, outside the metered
boundary. So a build's cost is compute joules, and re-running an identical build
costs **zero** new joules and makes **zero** model calls. The receipt carries
`executed_energy_uj` (joules actually spent) alongside `total_energy_uj`; the
difference is what the cache saved. This is the standard's structural answer to
the category's re-prompt / token-burn cost leak: it is recorded, signed, and
auditable, not hidden in opaque credits.
## Wasm steps and command steps
A step runs at the tier its work requires. A **wasm step** runs a unit in the
S2 sandbox (the default for agent-generated units). A **command step** runs a
real program — `cargo test`, `npm run build` — in the **S5 microVM**, for
attesting non-wasm source builds: the command is supervised as an isolated guest
(Firecracker on Linux+KVM; a process VMM elsewhere), its CPU metered, and the
run sealed at S5 (an escalation above the grant floor — the host attests it ran
in the microVM). Either way the step lands in the same signed receipt, content-
addressed (a command by `program ‖ args`), cached, and carrying its EAT — so one
build can span S2 wasm and S5 source-build steps and the receipt's tier floor is
the highest any step required.
## Speculative branching
A step **MAY** carry several candidate implementations. The build races them
**cheapest-first** and keeps the first that **verifies** (outcome `Completed`);
candidates after the winner are not run. The joules spent on losing candidates
are recorded as `speculative_energy_uj` — per step and summed on the receipt.
This is the honest posture of `jouleclaw-agent-app`: speculation trades energy
for confidence/latency, and that trade is **disclosed**, not hidden. Where the
category's tools silently burn tokens re-prompting a forgotten context, a
Sandbox build records "raced N candidates, kept the verified one, spent X µj on
the losers" — a number an auditor can see.
## Reference
`sandbox-build` implements the loop (`run_build`, `BuildReceipt`, `BuildCache`,
`BuildLedger`, `verify_build_receipt`) and ships a headless CLI. The MCP server
(`spec/mcp.md`) exposes it as the **`build`** tool, so an agent surface drives a
build and receives the signed receipt as the tool result — the backend an
editor such as agent-zed calls.