ci(standards-build): exercise the macOS energy backend, which nothing did #100

Merged
dcharlot merged 1 commit from ci/macos-energy-backend into main 2026-09-21 15:12:31 -04:00
Owner

jcp-energy's IOReport meter — the Apple Silicon rung of the energy ladder — is behind #[cfg(target_os = "macos")], and jcp-rs is pinned to the linux runner. A platform-gated test plus a single-platform runner assignment is zero coverage, and it is indistinguishable from passing: the code compiles out, the suite reports green, and nothing has been measured. Same family as a feature-gated test run with no --features, with target_os as the gate.

Not hypothetical

On 2026-09-19 the counter read 0 µJ across a full run on the dev Mac — IoReport::open() succeeding while read_uj() returned nothing. By 2026-09-21 it had healed with no code change in between (git log --since=2026-09-17 -- crates/jcp-energy/ is empty; 8 of 8 runs now pass). Both observations came from a human running the suite by hand. CI saw neither, and could not have.

That transience is the argument for the job, not against it. A permanently dead counter gets noticed once and then known. One that reads zero for a while and silently recovers means Meter::detect() can, during such a window, select a backend measuring nothing in preference to the time×power rung below it — and then it heals, so anyone investigating afterwards finds a working counter and concludes there was never a problem. A human spot-check is worst precisely at catching that.

Deliberately narrow

-p jcp-energy --lib only. jcp-rs stays on linux, so this adds the missing platform rather than trading one for the other, and costs one small crate instead of a second full workspace run. Every cfg(target_os = "macos") block in the crate lives in its lib tests, so --lib reaches all of them: 8 tests, 3 of them the IOReport ones.

Verified to catch the symptom, not merely to pass

Forcing read_uj() to return Some(0) makes cumulative_advances_after_cpu_burn fail with energy must advance: before=0 after=0 — byte-identical to the 2026-09-19 observation. Probe reverted, revert checked with git status.

What this deliberately does NOT do

It does not change energy-metering semantics. Meter::detect() still has no liveness probe, so it will still prefer a zero-reading IOReport backend over the rung below it. Deciding what detect() should do when a counter reads zero is a semantic change to the energy ladder and is left alone on purpose. This makes the condition visible; what to do about it is a separate call.

🤖 Generated with Claude Code

`jcp-energy`'s IOReport meter — the Apple Silicon rung of the energy ladder — is behind `#[cfg(target_os = "macos")]`, and `jcp-rs` is pinned to the **linux** runner. A platform-gated test plus a single-platform runner assignment is **zero** coverage, and it is indistinguishable from passing: the code compiles out, the suite reports green, and nothing has been measured. Same family as a feature-gated test run with no `--features`, with `target_os` as the gate. ## Not hypothetical On **2026-09-19** the counter read 0 µJ across a full run on the dev Mac — `IoReport::open()` succeeding while `read_uj()` returned nothing. By **2026-09-21** it had healed with **no code change in between** (`git log --since=2026-09-17 -- crates/jcp-energy/` is empty; 8 of 8 runs now pass). Both observations came from a human running the suite by hand. CI saw neither, and could not have. **That transience is the argument for the job, not against it.** A permanently dead counter gets noticed once and then known. One that reads zero for a while and silently recovers means `Meter::detect()` can, during such a window, select a backend measuring nothing in preference to the time×power rung below it — and then it heals, so anyone investigating afterwards finds a working counter and concludes there was never a problem. A human spot-check is worst precisely at catching that. ## Deliberately narrow `-p jcp-energy --lib` only. **`jcp-rs` stays on linux**, so this *adds* the missing platform rather than trading one for the other, and costs one small crate instead of a second full workspace run. Every `cfg(target_os = "macos")` block in the crate lives in its lib tests, so `--lib` reaches all of them: 8 tests, 3 of them the IOReport ones. ## Verified to catch the symptom, not merely to pass Forcing `read_uj()` to return `Some(0)` makes `cumulative_advances_after_cpu_burn` fail with `energy must advance: before=0 after=0` — **byte-identical** to the 2026-09-19 observation. Probe reverted, revert checked with `git status`. ## What this deliberately does NOT do It does not change energy-metering semantics. `Meter::detect()` still has no liveness probe, so it will still prefer a zero-reading IOReport backend over the rung below it. Deciding what `detect()` should do when a counter reads zero is a semantic change to the energy ladder and is left alone on purpose. This makes the condition **visible**; what to do about it is a separate call. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
ci(standards-build): exercise the macOS energy backend, which nothing did
All checks were successful
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 1m49s
standards workspaces build + test / aac-rs (pull_request) Successful in 37s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 39s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 34s
standards workspaces build + test / map-rs (pull_request) Successful in 39s
standards workspaces build + test / mesh-rs (pull_request) Successful in 1m3s
standards workspaces build + test / eoc-rs (pull_request) Successful in 1m49s
standards workspaces build + test / openpay (pull_request) Successful in 4m12s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m17s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m11s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m7s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 2m33s
standards workspaces build + test / arl-rs (pull_request) Successful in 3m23s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 2m31s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 2m31s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 2m29s
standards workspaces build + test / sense-rs (pull_request) Successful in 4m6s
standards workspaces build + test / macOS energy backend (jcp-energy) (pull_request) Successful in 1m59s
cf277b4828
`jcp-energy`'s IOReport meter — the Apple Silicon rung of the energy ladder — is
behind `#[cfg(target_os = "macos")]`, and `jcp-rs` is pinned to the linux runner.
A platform-gated test plus a single-platform runner assignment is **zero**
coverage, and it is indistinguishable from passing: the code compiles out, the
suite reports green, and nothing has been measured. Same family as a
feature-gated test run with no `--features`, with `target_os` as the gate.

Not hypothetical. On 2026-09-19 the counter read 0 µJ across a full run on the
dev Mac — `IoReport::open()` succeeding while `read_uj()` returned nothing — and
by 2026-09-21 it had healed with **no code change in between**
(`git log --since=2026-09-17 -- crates/jcp-energy/` is empty; 8 of 8 runs now
pass). Both observations came from a human running the suite by hand. CI saw
neither, and could not have.

That transience is the argument for the job rather than against it. A
permanently dead counter gets noticed once and then known. One that reads zero
for a while and silently recovers means `Meter::detect()` can, during such a
window, select a backend measuring nothing in preference to the time×power rung
below it — and then it heals, so anyone investigating afterwards finds a working
counter and concludes there was never a problem. A human spot-check is worst
precisely at catching that; a job that runs on every change is the instrument
for it.

Deliberately narrow: `-p jcp-energy --lib` only. `jcp-rs` stays on linux, so this
**adds** the missing platform rather than trading one for the other, and costs
one small crate instead of a second full workspace run. Every
`cfg(target_os = "macos")` block in the crate lives in its lib tests, so `--lib`
reaches all of them: 8 tests, 3 of them the IOReport ones.

Verified to catch the real symptom, not merely to pass: forcing `read_uj()` to
return `Some(0)` makes `cumulative_advances_after_cpu_burn` fail with
`energy must advance: before=0 after=0` — byte-identical to the 2026-09-19
observation. Probe reverted and the revert checked with `git status`.

This does **not** change energy-metering semantics. `Meter::detect()` still has
no liveness probe, so it will still prefer a zero-reading IOReport backend over
the rung below it; deciding what detect() should do when a counter reads zero is
a semantic change to the ladder and is left alone deliberately. This commit only
makes the condition visible.

Co-Authored-By: Claude Opus 5 <[email protected]>
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
Transaction-Science/open-standards!100
No description provided.