jcp-intercept: a reading meter meters a seam as one span, divided among its steps by CPU time #236

Merged
dcharlot merged 2 commits from feat/intercept-one-span-per-pass into main 2026-10-13 09:31:28 -04:00
Owner

Why

jcp-intercept metered every interceptor step as a span of its own.

Where the meter reads this process's energy count, each read first takes the reading thread off its core (#229), which costs tens of microseconds plus the read's own wake-up. An interceptor step (a redaction, a call-count check, an approval hold) is often a few microseconds, so a span of its own read mostly the meter. A chain of k interceptors also paid 2k reads per seam, 6k per model and tool call.

What

  • Counter-reading meters. A meter that reads a counter (graded HwShunt) now meters each seam's whole pass as one span, two reads per seam.
    • The steps are sealed after the span closes, in the order they ran.
    • Each gets its share of the reading by its own thread CPU time, which is exact to the nanosecond and needs no context switch to read.
    • The shares are integer µJ that sum to the reading exactly (largest remainder; a tie goes to the earlier step).
    • A share of a reading is ModelBased. A pass with one step keeps the reading's own grade. A Partial reading gives Partial shares.
    • The span also covers the chain's own digests and the meter's closing wake-up. All of it is divided among the steps, so no step is ever under its own energy.
  • Meters that read nothing (a model or a constant) cost nothing to run and still meter each step on its own. Receipts sealed with them are byte-identical; the pinned pre-coverage envelopes still match.
  • jcp-energy exposes the thread CPU clock it already had (thread_cpu_time).
  • Docs: the crate docs and jcp/README.md.

Evidence (M3 Ultra)

  • Unit tests:
    • shares sum exactly;
    • remainders go to the right steps;
    • equal split without CPU times;
    • coverage is kept, and lower grades are kept;
    • one step is not divided.
  • Real counter, 10 of 10 rounds. Three steps burning 2, 4 and 8 ms of their own CPU were sealed 10.8, 21.5 and 42.8 mJ, all ModelBased. The shares summed to the chain's figure every time, and to 96–97% of an independent ri_energy_nj read around the pass. That oracle folds its own way and shares no code with the meter.
  • Mutation checks:
    • metering per step always: fails;
    • shares kept as HwShunt: 3 tests fail;
    • remainder dropped: fails.
  • Suites: the jcp-rs workspace passes, 493 tests, and jcp-conformance passes. The Linux check is clean, and clippy reports nothing new in jcp-intercept or jcp-energy.
  • Vectors: no conformance vector pins an intercept/1 step's grade.

🤖 Generated with Claude Code

## Why jcp-intercept metered every interceptor step as a span of its own. Where the meter reads this process's energy count, each read first takes the reading thread off its core (#229), which costs tens of microseconds plus the read's own wake-up. An interceptor step (a redaction, a call-count check, an approval hold) is often a few microseconds, so a span of its own read mostly the meter. A chain of *k* interceptors also paid 2*k* reads per seam, 6*k* per model and tool call. ## What - **Counter-reading meters.** A meter that reads a counter (graded `HwShunt`) now meters each seam's whole pass as one span, two reads per seam. - The steps are sealed after the span closes, in the order they ran. - Each gets its share of the reading by its own thread CPU time, which is exact to the nanosecond and needs no context switch to read. - The shares are integer µJ that sum to the reading exactly (largest remainder; a tie goes to the earlier step). - A share of a reading is `ModelBased`. A pass with one step keeps the reading's own grade. A `Partial` reading gives `Partial` shares. - The span also covers the chain's own digests and the meter's closing wake-up. All of it is divided among the steps, so no step is ever under its own energy. - **Meters that read nothing** (a model or a constant) cost nothing to run and still meter each step on its own. Receipts sealed with them are byte-identical; the pinned pre-coverage envelopes still match. - **jcp-energy** exposes the thread CPU clock it already had (`thread_cpu_time`). - **Docs:** the crate docs and `jcp/README.md`. ## Evidence (M3 Ultra) - **Unit tests:** - shares sum exactly; - remainders go to the right steps; - equal split without CPU times; - coverage is kept, and lower grades are kept; - one step is not divided. - **Real counter, 10 of 10 rounds.** Three steps burning 2, 4 and 8 ms of their own CPU were sealed 10.8, 21.5 and 42.8 mJ, all `ModelBased`. The shares summed to the chain's figure every time, and to 96–97% of an independent `ri_energy_nj` read around the pass. That oracle folds its own way and shares no code with the meter. - **Mutation checks:** - metering per step always: fails; - shares kept as `HwShunt`: 3 tests fail; - remainder dropped: fails. - **Suites:** the jcp-rs workspace passes, 493 tests, and `jcp-conformance` passes. The Linux check is clean, and clippy reports nothing new in jcp-intercept or jcp-energy. - **Vectors:** no conformance vector pins an `intercept/1` step's grade. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Every interceptor step was metered as a span of its own. Where the meter
reads this process's energy count, each read first takes the reading
thread off its core (#229): tens of microseconds and its own wake-up. An
interceptor step is often a few microseconds, so a span of its own read
as mostly the meter, and a chain of k interceptors paid 2k reads per seam.

A meter that reads a counter now meters the whole seam pass as one span
(two reads per seam), and the steps are sealed after it closes, each with
its share of the reading by its own thread CPU time, which is exact and
read at no cost. The shares are integer micro-joules that sum to the
reading exactly (largest remainder); a share of a reading is ModelBased,
a pass of one step keeps the reading's own grade, and coverage is the
pass's. A meter that reads nothing (a model, a constant) still meters
each step on its own, so the receipts sealed with it are byte-identical.

jcp-energy exposes the thread CPU clock it already had
(`thread_cpu_time`). On the M3 Ultra, three steps burning 2, 4 and 8 ms
were sealed 10.8, 21.5 and 42.8 mJ, summing to the chain's figure and to
96-97% of an independent read around the pass, in 10 of 10 rounds.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
jcp README: how an intercept step's joules are metered where the meter reads a counter
All checks were successful
energy meters on real hardware / RAPL and NVML on jetson-hub (pull_request) Successful in 42s
standards workspaces build + test / jouledesk-rs (pull_request) Successful in 54s
standards workspaces build + test / jouleclaw-rs (pull_request) Successful in 2m22s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 4m30s
standards workspaces build + test / aac-rs (pull_request) Successful in 2m36s
standards workspaces build + test / joule-code-rs (pull_request) Successful in 1m22s
standards workspaces build + test / joulecontract-rs (pull_request) Successful in 56s
standards workspaces build + test / map-rs (pull_request) Successful in 54s
standards workspaces build + test / mesh-rs (pull_request) Successful in 52s
standards workspaces build + test / openpay (pull_request) Successful in 3m6s
lockfiles / every Cargo.lock is current (pull_request) Successful in 31s
no-vanity-metrics / Scan committed Markdown for vanity metrics (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no comparison (pull_request) Successful in 3s
no-vanity-metrics / WAI public text names no company or product (pull_request) Successful in 3s
standards workspaces build + test / arl-rs (pull_request) Successful in 1m9s
standards workspaces build + test / eoc-rs (pull_request) Successful in 2m7s
standards workspaces build + test / jcp-rs (pull_request) Successful in 1m40s
standards workspaces build + test / joule-ui-rs (pull_request) Successful in 1m10s
standards workspaces build + test / joulehook-rs (pull_request) Successful in 1m10s
standards workspaces build + test / proof-rs (pull_request) Successful in 1m17s
standards workspaces build + test / sense-rs (pull_request) Successful in 1m14s
standards workspaces build + test / sandbox-rs (pull_request) Successful in 2m23s
standards workspaces build + test / smart-byte-rs (pull_request) Successful in 3m46s
e00db437c6
Co-Authored-By: Claude Opus 5.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!236
No description provided.