ci(standards-build): run all five IOReport meters on macOS, and fail a step whose test never ran (merge LAST) #102
Merged
dcharlot
merged 5 commits from 2026-10-01 23:37:35 -04:00
ci/macos-energy-widen into main 2026-10-01
ci: build and run the energy meters' NVML-gated tests
All checks were successful
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 47s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 1m5s
wai formal verification (integer core) / kani (pull_request) Successful in 4m15s
WAI JPEG-AI whole decode (pinned inputs, required) / fetch pinned JPEG-AI inputs → whole decode + pixel hash, required (pull_request) Successful in 1m1s
WAI neural decoders end-to-end / synthetic fixtures → Rust decode → reference (±4) (pull_request) Successful in 1m6s
WAI neural sink gates / model-free refusals of the neural sink (pull_request) Successful in 45s
WAI section references / cited sections exist (pull_request) Successful in 9s
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Successful in 3m41s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 1m37s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 16m3s
standards workspaces build + test / aac-rs (pull_request) Successful in 5m33s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 4m18s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 3m7s
standards workspaces build + test / map-rs (pull_request) Successful in 5m44s
standards workspaces build + test / mesh-rs (pull_request) Successful in 2m36s
standards workspaces build + test / openpay (pull_request) Successful in 12m8s
wai cross-architecture byte-equality / linux-aarch64 (pull_request) Successful in 1m19s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 8m29s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 1m11s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 2m30s
standards workspaces build + test / arl-rs (pull_request) Successful in 2m20s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 2m56s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 2m57s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 2m47s
standards workspaces build + test / sense-rs (pull_request) Successful in 2m50s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 4m21s
wai cross-architecture byte-equality / macos-arm64 (reference) (pull_request) Successful in 30s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 4m57s
WAI conformance / cross-arch byte-equality · macos (pull_request) Successful in 28s
WAI energy receipts / energy receipts · macos (pull_request) Successful in 1m26s
jcp-energy `nvml`, eoc-meter `cuda` and jouleclaw-energy `nvml` are features no workspace member enables, so `cargo test --workspace` never compiled the NVML backends, nor ran the tests behind them. That includes #129's plausibility rule, which marks a counter that runs past its board Implausible. A matrix field `feature_tests` now runs those crates once more with the feature on. In the container there is no GPU and powercap is masked, so the hardware tests take their "unavailable, and the oracle agrees" branch. The unit tests behind the features run in full. Co-Authored-By: Claude Opus 5.5 <[email protected]>
ci: run joule-code-remediate's formal gate against a real z3
joule-code-remediate's formal gate shells out to z3, and neither job that tests it installed a solver: joule-code-rs in standards-build, and the joule-code conformance gate. Its z3 tests used to return early without a solver, so CI passed without ever running the real-solver path. sandbox-meter/cpu-rail-liveness (#114) makes those tests assert in both branches, and adds JOULE_FIX_EXPECT_Z3=1 to turn a missing solver into a failure. joule-code-rs now joins the `z3: true` matrix entries, as joulecontract-rs already does on the same runner kind. The conformance gate installs z3 the same way. Both set JOULE_FIX_EXPECT_Z3=1 where z3 was installed. Elsewhere the variable is empty, and only joule-code- remediate reads it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
ci(standards-build): describe the liveness rule the meters now use
The job's comment said a meter uses IOReport once the CPU rail advances in two separate intervals. The five meters have since tightened that rule. A refresh can be published in steps: one was caught as +61.8 kJ, then +3.4 J 64 ms later. So two advancing intervals can still be a single refresh. Now the rail has to advance in at least 5 intervals, in at least 4 of every 5, over at least 300 ms. Comment only. Co-Authored-By: Claude Opus 5.5 <[email protected]>
ci(standards-build): run each IOReport meter's integration tests on macOS too
Each of the five meter crates now has a tests/ file that checks its CPU-rail liveness probe runs exactly once per process: jcp-energy (ioreport_probed_once), sandbox-meter (ioreport_probe_once_per_process), proof-cascade (ioreport_once, ioreport_unopenable), eoc-meter (liveness_probe_once_per_process) and jouleclaw-energy. Those checks only hold in a fresh process, so they are integration tests. `cargo test --lib` skipped them, so a per-thread or re-probing cache would have passed this job. Dropping `--lib` runs them too, and the `ioreport liveness:` guard is unchanged. Co-Authored-By: Claude Opus 5.5 <[email protected]>
ci(standards-build): run all five IOReport meters on macOS, and fail a step whose test never ran
The macOS energy job ran only jcp-energy. Four more crates carry an Apple
Silicon IOReport meter: proof-cascade, eoc-meter, jouleclaw-energy and
sandbox-meter. Each is behind cfg(target_os = "macos"), jouleclaw-energy also
behind its `ioreport` feature, and every one of their workspaces is pinned to a
linux runner. None of them had ever run on the platform whose private API they
call.
This replaces this branch's first version (07fb8360), which rested on a wrong
premise. That version added three of the crates and left sandbox-meter out
with a comment saying it failed where jcp-energy passed "because they read
IOReport differently". They do not. Both read the same CPU rail, and on
macOS 27 an unprivileged reader does not see that rail move: it is republished
only in rare lumps. jcp-energy's old test asserted that the summed rails
advanced, which the live GPU rail satisfied whenever something drew on screen.
sandbox-meter's asserted the CPU class itself, so it failed. The three steps
the first version added passed for the same vacuous reason.
The job's header was wrong in the same way. It described a 2026-09-19 zero
that had "healed" by 09-21, and cited cumulative_advances_after_cpu_burn as
proof that it catches the real symptom. That test was satisfied by the GPU
rail, and the jcp-energy fix deletes it.
What the job checks now. Each meter uses IOReport only when the CPU rail
itself advances in at least two separate intervals while the probe burns CPU,
and otherwise falls back to its estimator. Its tests assert against an
independent oracle. That makes the job deterministic: green while every meter
declines a rail that does not keep moving, red if any selects one.
Each step runs with --nocapture and fails unless the output contains the
`ioreport liveness:` line. Only the platform-gated frozen-rail test prints it,
so a filter, a missing feature or a cfg that leaves zero tests to run can no
longer pass as green. Without --nocapture a passing test's eprintln! is
captured, which is why the line never appeared in the old job's log.
Merge last: the steps run the new tests from the five meter branches, and
sandbox-meter's current test fails on main.
Co-Authored-By: Claude Opus 5.5 <[email protected]>