jcp: C25 — flow was a declared clause with no check; now it has one #357
Merged
dcharlot
merged 1 commit from 2026-10-20 13:06:03 -04:00
feat/c27-flow-conformance into main 2026-10-20
jcp: C25 — flow was a declared clause with no check; now it has one
All checks were successful
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 6s
repository checks / lockfiles, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Successful in 45s
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 7m45s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 7m31s
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 1m28s
standards workspaces build + test / macOS energy backends (pull_request) Successful in 8m20s
standards workspaces build + test / jouledesk-rs (jouledesk/jouledesk-rs, jouledesk-rs, macos) (pull_request) Successful in 2m47s
standards workspaces build + test / jcp-rs (jcp-conformance, jcp/jcp-rs, -p jcp-energy --features nvml, jcp-rs, linux) (pull_request) Successful in 1m49s
standards workspaces build + test / joule-ui-rs (joule-ui/joule-ui-rs, joule-ui-rs, linux) (pull_request) Successful in 1m17s
standards workspaces build + test / joulehook-rs (joulehook/joulehook-rs, joulehook-rs, linux) (pull_request) Successful in 1m18s
standards workspaces build + test / sandbox-rs (sandbox-conformance, sandbox/sandbox-rs, sandbox-rs, linux) (pull_request) Successful in 2m38s
§9 has listed `C25 — flow` as a conformance clause for as long as the clause existed, and the harness never had it. Worse than a missing test: a published list of conformance classes claiming a class the pack cannot run. Verified before writing anything, because a declared gap is not evidence of one: - the harness's only occurrence of "flow" was an unrelated `// control flow` comment; - `jcp-flow` is not even a dependency of `jcp-conformance`, so no check could have used it; - and `jcp-flow` is the wrong crate anyway — it is provenance *scanning* (L17–L20, content windows). The clause is about the *decision*: a grant's ceiling, the enforcement point's taint floor, attenuation. That lives in `jcp_schema::flow` and `jcp-runtime`, both already dependencies, so the check needs no new one. `C25` asserts each property the clause states, separately, so a failure names which one broke: - a label at or below the grant's ceiling passes and one above it does not; - the enforcement point's taint floor binds **even under a ceiling permissive enough to admit the value** — an operator refusal a delegated grant cannot widen; - facts that were never computed **fail closed** against a ceilinged grant. This is the unknown-is-not-a-value rule in its sharpest form: "no provenance" must not read as "no taint"; - several ceilings compose to the strictest, so adding a permissive caveat cannot widen a strict one; - a flow denial debits nothing, so a tainted call costs zero joules; - a ceiling-free grant — which is every grant minted before flow existed — behaves identically whatever the facts say and carries no flow field on the wire. Falsified against the implementation rather than the check, which is the only direction that means anything for a conformance clause: four mutations of `flow_gate` and `ceiling_of` (ceiling unenforced, floor unapplied, uncomputed provenance failing **open**, ceilings composing to the most permissive). All four caught, each with its own message, so the clause discriminates between the properties instead of failing generically. Also fixes the asymmetry in the other direction: the harness has carried a `C19` (injection resistance) that §9 never listed, so §9 now lists it. The spec's classes and the harness's checks are both C1–C26 and agree item for item. I first wrote this as `C27`, taking the next free id. That was wrong — §9 had already assigned `C25` to flow, and implementing a different id would have recreated the asymmetry this closes. Co-Authored-By: Claude Opus 5 <[email protected]>