jcp: WithinWindow, a sliding-window caveat over calls, payloads and measured joules #388
Merged
dcharlot
merged 1 commit from 2026-10-21 10:20:15 -04:00
feat/jcp-window-caveat into main 2026-10-21
jcp: WithinWindow, a sliding-window caveat over calls, payloads and measured joules
All checks were successful
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 4s
wai-pack / wai-pack · linux (pull_request) Has been skipped
wai-pack / wai-pack · linux-arm64 (pull_request) Has been skipped
wai-pack / wai-pack · macos (pull_request) Has been skipped
wai-quantum studio and desktop / does this change touch it (pull_request) Successful in 4s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Has been skipped
wai-pack / wai-pack · the floor through a media prober (pull_request) Has been skipped
wai-quantum studio and desktop / studio · browser (pull_request) Has been skipped
wai-pack / wai-pack · dependency licences (pull_request) Has been skipped
wai-quantum studio and desktop / desktop app · macos (pull_request) Has been skipped
wai-quantum WebGPU member / does this change touch it (pull_request) Successful in 5s
wai-quantum WebGPU member / shader checks · browser build · wasip2 inertness · MSRV (pull_request) Has been skipped
wai-quantum WebGPU member / member · software Vulkan (linux) (pull_request) Has been skipped
wai-quantum WebGPU member / member · Metal (macos) (pull_request) Has been skipped
wai-quantum WebGPU member / member · discrete GPU, Vulkan (jetson-hub) (pull_request) Has been skipped
WAI mbt2018_mean integer decode (regenerated vectors) / does this change touch it (pull_request) Successful in 4s
wai-quantum WebGPU member / member · integrated GPU, Vulkan (framework-128gb) (pull_request) Has been skipped
wai-quantum WebGPU member / member · browser WebGPU (macos) (pull_request) Has been skipped
WAI mbt2018_mean integer decode (regenerated vectors) / regenerate mbt2018_mean integer vectors → Rust decode, required (pull_request) Has been skipped
wai-web wasm32 / does this change touch it (pull_request) Successful in 4s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Has been skipped
standards workspaces build + test / jcp-rs (jcp-conformance, jcp/jcp-rs, -p jcp-energy --features nvml, jcp-rs, linux) (pull_request) Successful in 1m47s
standards workspaces build + test / joule-ui-rs (joule-ui/joule-ui-rs, joule-ui-rs, linux) (pull_request) Successful in 1m11s
standards workspaces build + test / joulehook-rs (joulehook/joulehook-rs, joulehook-rs, linux) (pull_request) Successful in 1m14s
standards workspaces build + test / sandbox-rs (sandbox-conformance, sandbox/sandbox-rs, sandbox-rs, linux) (pull_request) Successful in 2m33s
standards workspaces build + test / jouleclaw-rs (-nodebug, jouleclaw/jouleclaw-rs, -p jouleclaw-energy --features rapl,nvml, jouleclaw-rs, linux-arm64, -C target-feature=+fp16) (pull_request) Successful in 2m22s
standards workspaces build + test / mesh-rs (mesh/mesh-rs, -p mesh-engine-gguf -p mesh-openai --features mesh-engine-gguf/gguf,mesh-openai/server, mesh-rs, linux-arm64) (pull_request) Successful in 1m2s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 3m16s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 7m34s
standards workspaces build + test / jouledesk-rs (jouledesk/jouledesk-rs, jouledesk-rs, macos) (pull_request) Successful in 2m48s
A grant's budget bounded its whole life and not its rate: a day's budget
could go in a minute. jcp-runtime budgets were cumulative only.
jcp-schema:
- Caveat::WithinWindow(Window { secs, limit }), where limit is
WindowLimit::{MaxUj, MaxCalls, MaxDistinctPayloads}.
- DenyReason::WindowExceeded ("window-exceeded").
- holds() refuses only a zero-second window. Like FlowBelow, a window is
decided by a runtime gate against state, not from the frame.
jcp-runtime (SPEC §4.12):
- Per grant carrying a window, a history of admissions (time, payload) and
debits (time, µJ), pruned to the grant's longest window.
- A call counts once admitted: allowed in a one-shot decide, or authorised
in the two-phase path. A denied call counts for nothing and is debited
nothing. Every path gates and records: decide, decide_priced,
decide_flow, authorize, authorize_flow, the chained paths and every
charge. Every link of a chain is counted, so a parent's window bounds its
delegates together.
- A joule window refuses a one-shot call whose cost would overfill it. In
the two-phase path it admits while any of the window is left and binds at
the debit: an overrun is denied window-exceeded and stays debited, as
MaxCostUj does.
- A debit that arrives without its time (charge, charge_chained) is placed
at the grant's latest admission, never earlier than its own call's, so
its joules stay in a window at least as long as they should. A debit with
no admission at all stays in every window. No caller signature changed.
- restore(), a timeless spend ledger, leaves every window counted as full
until resume_windows_at(t) names when history is complete and a whole
window has passed since. An unknown history is not an empty one.
- authorize_chained_for(…, need_uj) takes a caller's ceiling into the
budget test, so a call refused for its ceiling is refused before it is
admitted.
mesh-core: authorise with the request's joule ceiling via
authorize_chained_for, replacing the after-the-fact BudgetTooLow check.
A serve refused for its ceiling therefore fills no window. The errors and
their figures are unchanged.
jcp-bridge: a window caveat is unprojectable into an OAuth token.
Durability: jcp-wire and mesh-core replay each decision through the gate at
its recorded time, so windows rebuild across a restart (tests in both). The
gateway resumes from receipts, which carry no time, so its windows stay
full after a resume (its clock is also fixed at 0, a separate gap).
SPEC:
- §4.12: semantics, durability, sharding (n points admit n × the limit
unless they share history).
- The §4.9 wire form.
- Conformance class C27, with a C27 check in jcp-conformance.
Also: two pre-existing clippy errors (cloned_ref_to_slice_refs) in
jcp-runtime's tests, so the crates touched are clippy-clean.
Tests: 10 in jcp-runtime, 1 in jcp-wire, 1 in mesh-core, plus the bridge
case and C27. Mutation testing: 30 mutants, all killed. They cover every
limit's boundary, the slide, debit placement (latest, not first; MAX, not
0, without an admission), the restore gap, pruning, the ceiling-before-
admission test, and each path's gate and recording.
Verified on the build host:
- jcp-rs: 575 tests, 119 behind features, every conformance class.
- mesh-rs: 95 tests.
- Clippy -D warnings clean on jcp-schema, -runtime, -bridge, -wire,
-conformance and mesh-core.
- sandbox-rs, joule-code-rs, jouledesk-rs, joulehook-rs and joule-ui-rs
compile with --all-targets.
- Repo checks pass.
Co-Authored-By: Claude Opus 5.5 <[email protected]>