Add a coherent set of long-running-agent capabilities, each as a spec section + reference implementation + conformance class, every one metered, attested, and receipt-chained. Sandbox: - §13 Durable run records (C6): the receipt chain IS the resumable run; execute/suspend/resume segments hash-chained; idle energy metered across parks. (sandbox-attest::runrecord) - §14 Environment manifest (C7): devcontainer.json declarative-subset ingestion -> canonical, content-addressed, signed manifest; command/widening and unknown fields refused. (sandbox-attest::manifest) - §5.5 Content-addressed process control (C8): exec allow/deny by BLAKE3 of the binary; denylist absolute, survives rename/move/wrapper. - §15 Warm pools (C9): a claim attributes accrued idle energy to the run (a fast start has a visible joule price); evictions record overhead, not zero. (sandbox-attest::warmpool) - §16 Fleet records (C10): merkle aggregate receipt over per-item runs; log-size membership proofs. (sandbox-attest::fleet) - durable.json cross-impl wire vectors + file-backed verify. JCP: - §4.6 Standing grants (C20): a signed mint policy turns a held grant into bounded, rate-limited, event-triggered children via the attenuation path. (jcp-grant::standing) - §4.7 Checkpoints + amendments (C21): mid-run steering under separation of duties — the agent checkpoints its own state, only the issuer (a distinct principal) may amend, and only to tighten. (jcp-grant::checkpoint) - standing.json cross-impl vectors. Both workspaces green; conformance harnesses pass with no skips; clippy clean. Co-Authored-By: Claude Opus 4.8 <[email protected]>
79 lines
3.6 KiB
Markdown
79 lines
3.6 KiB
Markdown
# Durable run records
|
|
|
|
Agent work is no longer minutes long. The valuable runs span hours or days,
|
|
outlive the machine that started them, pause for review, and resume elsewhere.
|
|
Most platforms make the *process* the unit of survival and keep it alive in a
|
|
cloud sandbox. This standard takes the stronger position: **the record is the
|
|
run**. An execution is a chain of sealed segments; the sandbox that hosted any
|
|
one segment is disposable, and what survives — what can be suspended for a
|
|
week, restored on different hardware, and handed to an auditor afterwards — is
|
|
the run record.
|
|
|
|
## The record
|
|
|
|
A **run record** is an append-only, hash-chained sequence of **segments**
|
|
belonging to one unit under one grant set. The genesis head binds both:
|
|
|
|
```
|
|
head₀ = BLAKE3("sandbox.runrecord/1" ‖ unit_id ‖ grants_id)
|
|
headₙ = BLAKE3(headₙ₋₁ ‖ segmentₙ)
|
|
```
|
|
|
|
Two records can never be spliced — not across units, and not across grant
|
|
sets. A continuation that wants different grants is a **new run**.
|
|
|
|
Three segment kinds:
|
|
|
|
- **Executed** — one active interval, recorded by the content address of its
|
|
attestation (§7), which already binds the interval's energy receipt (§6),
|
|
replay-journal root (§8) and outcome. Nothing is re-stated; the record
|
|
points at sealed objects.
|
|
- **Suspended** — the run parked. Records a **snapshot reference**: the
|
|
content addresses of the retained filesystem root, the memory image if the
|
|
executor retains resident state (S5 snapshots), and the environment
|
|
manifest the run was created from.
|
|
- **Resumed** — the run un-parked. Records the snapshot reference restored
|
|
and the **idle energy** the retained state drew while parked.
|
|
|
|
## Resumption preconditions
|
|
|
|
A host **MUST** refuse to resume unless:
|
|
|
|
1. the offered snapshot is content-identical (by address) to the one recorded
|
|
at suspension — a forked or tampered snapshot breaks the chain rather than
|
|
silently continuing it;
|
|
2. the resuming environment satisfies the recorded manifest address — "same
|
|
toolchain" is checked by hash, not by trust;
|
|
3. the record verifies from genesis: head recomputation, strict
|
|
execute/suspend/resume phase alternation, and snapshot identity at every
|
|
resume.
|
|
|
|
A record may be **closed** at any point, including while parked — abandonment
|
|
is an honest outcome and leaves an auditable stub.
|
|
|
|
## Energy honesty across suspends
|
|
|
|
A parked run is not free. Retained volumes, snapshot storage and warm-pool
|
|
residency draw power continuously. Each *Resumed* segment carries `idle_uj` —
|
|
the microjoules attributed to the retained state for the parked interval,
|
|
under the same provenance discipline as live metering (§6.2): measured where
|
|
the host can measure, estimated and labelled where it cannot. The total cost
|
|
of a run is the sum over its receipts **plus** its idle energy; a host that
|
|
reports only active-interval joules for a week-long run does not conform.
|
|
|
|
## Relation to the audit chain
|
|
|
|
The S7 audit chain (§7.7) orders *runs* within a steward's domain; the run
|
|
record orders *segments* within one run. They compose: each executed segment's
|
|
attestation may itself carry `audit_prev`, and a continuation attestation
|
|
SHOULD cite the run record's current head, mirroring that convention.
|
|
|
|
## Conformance
|
|
|
|
Class **C6** (§10): chain advance and verification across
|
|
execute → suspend → resume → execute; refusal of forked snapshots
|
|
(`SnapshotMismatch`); refusal of phase violations (execution while parked);
|
|
idle-energy accumulation; tamper-evidence through the wire form (a modified
|
|
recorded snapshot must fail verification); refusal of appends after close.
|
|
|
|
The reference implementation is `sandbox_attest::runrecord`.
|