open-standards/proof
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Transaction Science 974a8ebece
All checks were successful
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 10s
energy meters on real hardware / sink decode table · per-task energy and the GPU rail on macOS (pull_request) Successful in 2m16s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 2m26s
standards workspaces build + test / joulecontract-rs (joulecontract/joulecontract-rs, joulecontract-rs, linux-arm64, true) (pull_request) Successful in 1m0s
standards workspaces build + test / proof-rs (proof/conformance/v1/joulespec.toml, proof-conformance, proof/proof-rs, proof-rs, linux, true) (pull_request) Successful in 2m24s
energy meters on real hardware / RAPL and NVML on jetson-hub (pull_request) Successful in 36s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 6m4s
energy meters on real hardware / sink decode table · RAPL on jetson-hub (NVML surveyed) (pull_request) Successful in 2m25s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 10m58s
proof-cascade: RAPL MSR domains are per die on Intel, per package on AMD
Linux scopes Intel's RAPL energy-status MSRs per die: its RAPL PMU treats
the package counter as package-scope only on AMD and Hygon
(rapl_pkg_pmu_is_pkg_scope(), arch/x86/events/rapl.c: "AMD/HYGON platforms
have a per-PKG package energy counter", "CLX-AP is multi-die and its RAPL
MSRs are die-scope"), and its powercap driver names a zone
package-<p>-die-<d> where the MSRs are not package-scope and a package holds
more than one die (intel_rapl_common.c). The MSR fallback grouped CPUs by
physical_package_id alone, so on a multi-die Intel package it read one die
and missed the rest: an under-count, the unsafe direction at a ceiling.

MSR fallback: on Intel family 6 a domain is (physical_package_id, die_id),
die 0 where the kernel lists no die_id; on AMD Zen and Hygon it stays the
package, whatever die_id says. Each domain is read on its lowest-numbered
CPU and is a package zone of its own, indexed in (package, die) order, so
each die is a rail of its own in the liveness rule and every die is summed.
All-or-nothing, the zero unit, the wrap and powercap preferred are as
before. (MsrPackage is now MsrDomain.)

Powercap: is_package_name also accepts package-<digits>-die-<digits>, and
nothing looser, so a multi-die host's per-die zones are its packages:
powercap lists a package (the MSRs are not read), and both die zones are
summed. Before, such a host listed no package and fell to the MSRs, as root
only.

The RAPL hardware test's oracle follows the same rules with its own code.

Tests (fake files): two Intel packages of two dies each, four domains each
read on its own die's first CPU and summed; an AMD package whose CPUs carry
two die_ids, one domain; an Intel host with no die_id files, per package; a
two-die powercap tree summing both die zones and not psys; and the name rule
(package-0-die-0 yes; package-0-die-, package-0-die, package--die-0,
package-0-die-x, package-0-core-0 no). proof-cascade and proof-cli tests pass
on Linux, proof-cascade on macOS (with its ioreport liveness grep); clippy
is clean with -D warnings on Linux (proof-cascade, proof-cli) and macOS
(proof-cascade, proof-solvers).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-04 21:19:50 -05:00
..
conformance/v1 joulespec: applied to a standard that is not its own, which found a mis-aimed mutation 2026-11-02 04:27:13 -05:00
proof-rs proof-cascade: RAPL MSR domains are per die on Intel, per package on AMD 2026-11-04 21:19:50 -05:00
CONTRIBUTING.md
LICENSE
LICENSE-SPEC
README.md proof-cascade: RAPL MSR domains are per die on Intel, per package on AMD 2026-11-04 21:19:50 -05:00
SPEC.md proof-solvers: grade wall time × the default 15 W Estimator, not ModelBased 2026-10-11 10:11:54 -04:00

proof — A Carrier for Verified Work

The verification cargo class of the substrate. A proof obligation is content-addressed; a solver is anything that can attempt one at a declared tier; a discharged obligation seals as a signed JCR-1 receipt that records which tier closed it and the joules it cost. The standard fixes the one axis the theorem-proving field leaves implicit — joules per verified proof — and makes it portable: any prover can emit a Proof receipt, and any auditor can verify it with the same tooling as a Map, Sandbox, or Joule Code receipt.

The cheapest sufficient solver wins. Every obligation goes to the cheapest rung that can discharge it — deterministic automation (T0), then SMT (T1), then a small distilled prover (T2), then a frontier model (T3, last resort) — and escalates only on failure. Correctness is never traded for energy: a solver returns proved only when a verifier would accept the artifact, so the standard changes which tier pays for a proof, not whether it is checked. The joules spent on a cheaper solver that ran and failed first are disclosed as the cost of escalation, never hidden. Energy carries an honest provenance tag (HwShunt / ModelBased / Estimator), and a receipt for an Ungrounded statement says, in the signed artifact, that the statement was never validated against intent — a proof is not a specification.

  • Site: jouleproof.transaction.science (the JouleProof pillar is the steward + services layer over this standard).
  • Licence: Apache-2.0 for reference code (see LICENSE); CC-BY-4.0 for specification text (see LICENSE-SPEC).
  • Status: v0.1.0 draft. Specification core published (SPEC.md); reference workspace proof-rs/.

What's here

proof/
├── SPEC.md            — the normative standard (§1–§9)
├── conformance/v1/    — published vectors (receipt wire + signed core + envelope)
└── proof-rs/          — the Apache-2.0 reference implementation

The reference implementation (proof-rs/)

  • proof-schema — the content-addressed goal (blake3(statement‖0x00‖context)), the cheapest-first tier ladder, the honest energy model (HwShunt/ModelBased/Estimator with the coupling enforced), SpecGrounding, the verdict, and the Solver trait every backend implements. Canonical det-CBOR content addressing.
  • proof-solvers — two real rungs, their energy estimated from measured wall time (Estimator: wall time × a default ~15 W power that no host calibrated — not a hardware reading, and not a calibrated model): a propositional decider (T0) that parses a boolean goal and decides validity by truth-table in process, and z3 (T1) — shell or kept resident across goals — that decides an SMT-LIB goal (assert the negation; unsat ⇒ valid). The resident z3 is the one rung read off hardware: where the kernel counts each process's CPU energy live (macOS), each decision is read off the resident z3's own process tree, and the attempt is that reading (HwShunt) only when the reading saw nothing missing — no gap of any kind — the decision ran entirely in the tree, and the operator has declared that the z3 it runs decides in its own process (Z3Server::declared_self_contained; proof reads PROOF_Z3_SELF_CONTAINED=1) — a tree reading cannot see work handed to a container, VM or remote solver, so a forwarding z3 would read whole. Otherwise (a gapped reading, no declaration, a refutation whose counter-model a one-shot z3 fetches outside the tree, Linux) it keeps the wall-time estimate and records why, beside the absolute path of the z3 binary that ran. Each goal is decided as a fresh z3 would decide it: the answer is read off the crate's own (check-sat) before an unpredictable per-goal end marker, an error anywhere is undecided, and the resident session is replaced after any goal that sets an option or is not answered cleanly. Each refuses rather than fakes, so the router escalates. The model rungs (T2/T3) are honest stand-ins behind the same trait.
  • proof-cascade — the escalation router (every joule accounted, wasted_uj disclosed, and a goal's figure graded by the weakest of the attempts it sums), the content-addressed proof cache (the energy flywheel, durable as line-delimited JSON), batch energy accounting against a frontier-only baseline with the per-tier Amdahl breakdown, and a real hardware energy meter (meter — the HwShunt backend): it runs a real proof on every spare core and returns its measured microjoules from the first live source — on macOS this process's own CPU energy counter (proc_pid_rusage's ri_energy_nj, public API, no privilege), read before the workers start and after they are joined, so other processes are excluded by construction and no idle baseline is subtracted; else IOReport's Energy Model, read directly through its C API on Apple Silicon and bracketed against idle; on Linux RAPL's package counters, bracketed against idle — so the headline joules per verified proof can be a real reading, not only a model. A vendor or kernel counter's reading is graded HwShunt only while the counter is live for the domain it claims (SPEC.md §5), and the meter checks that before it meters anything, by one rule for every source (the counter keeps advancing in at least 5 sample intervals, at least 4 of every 5, over at least 300 ms while the probe burns CPU): the process counter itself, every IOReport CPU energy rail the figure sums (CPU Energy, or each die's DIE_<n>_CPU Energy), every RAPL package counter the figure sums (psys is neither summed nor probed). Each figure carries its domain: the process counter's is this process's CPU energy only — not other processes, child processes, GPU, ANE or DRAM. Returns nothing where no source is live — the caller keeps its honestly-tagged estimate rather than inventing a figure.
  • proof-receipt — the proof/1 JCR-1 receipt: canonical det-CBOR + COSE_Sign1/EdDSA, vendored byte-compatible with the family's cross-language verifiers; refuses to seal an unproved goal.
  • proof-conformance — C1–C5 + a negative pack, all checks real, published vectors in conformance/v1/.
  • proof-cli — the proof reference demo: a proof workload reporting joules-per-proof against a frontier-only baseline — like for like, charged only for the goals the cascade proved, with the all-goals figure and its goal count beside it — the Amdahl breakdown, the cache flywheel, and a sealed + verified receipt. proof --measure adds a real hardware reading of a non-trivial T0 proof (HwShunt) where the meter produces one, and prints which source metered it, its domain, and why each other source was not used; that needs a counter the meter has seen to be live. On the Macs measured so far (macOS 27.0.1, an M5 Max and an M3 Ultra) IOReport's CPU energy rail is frozen for an unprivileged reader, but this process's CPU energy counter is live, so --measure meters with it; the receipt still seals the cascade's own Estimator figure for the first goal. On Linux, RAPL's energy_uj is root-only on current kernels; where powercap lists no package (a kernel without the intel_rapl_msr driver), the meter reads the energy-status MSRs instead — each die on Intel, each package on AMD and Hygon, as Linux scopes them — which needs CAP_SYS_RAWIO.

cargo test --workspace green; cargo clippy --workspace --all-targets is warning-free for Linux, and on macOS reports two lints in proof-cascade's IOReport FFI. The two bottom rungs decide for real, with energy estimated from wall time (the resident z3's decisions read off its own process tree where that reading is whole and the z3 declared self-contained); the model rungs are honestly marked as stand-ins until inference backends are wired.

Honesty the standard records

  • A proof is not a specification. spec_grounding rides in the signed receipt; Ungrounded is the default and a prover may never self-certify it.
  • The multiple shrinks with difficulty. The accounting reports energy per closing tier, so the few hardest goals dominating the joules (Amdahl) is visible, not averaged away.
  • Energy is reported at all — per proof, with an honest provenance tag — which the field otherwise leaves to be inferred from device-days.