jcp §4.10: the flow gate had no spec section, and six code references cited it #190
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/revocation-freshness"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
jcp-runtimecites "SPEC §4.10" in six places — the taint floor, the flowgate, check 6c — and
jcp/SPEC.mdhas no §4.10. The section was never written.So the mechanism that decides whether a value's provenance may exercise a grant
is implemented, gate-enforcing and tested, with no normative text behind it.
That is the mirror of what this sweep has mostly been closing: a check with no
claim, rather than a claim with no check.
I found it by nearly colliding with it — #189 had taken §4.10 for durable spend,
and is renumbered to §4.11, because the code had already spoken for the number.
§4.10 documents what is there
Every normative sentence is backed by a test that already exists in
jcp-runtime:⊥and⊤;FlowBelowcaveat, several composing to the strictest viameeton the label andminon the tainted sub-budget, so attenuation neverwidens one;
trust root (§7), default-open;
⊥"Not computed" MUST NOT be read as "clean".
a ceiling inside an unauthenticated grant would seal a verdict over
attacker-chosen policy; before caveats and budget, so a tainted call costs
zero joules.
A sentence I had to pull back
I first wrote that the implementation propagates labels. It does not —
flow_gatetakes the facts from its caller, so propagation belongs to thehost, the only party that sees the data move. The spec now says so, and says
what JCP guarantees instead: a host that propagates gets a decision bound to
what it reported, and one that does not gets a refusal rather than a pass.
Conformance class C25 is declared and defined in §9's list — citing a class
without defining it would be the same dangling reference this PR exists to fix.
§4.3 gains a Propagation paragraph
§4.3 binds an enforcement point once it holds a revocation, and says nothing
about how it comes to hold one. With a budget sharded across N points (§4.5), a
revocation that reached three of five leaves the grant live at two — and an allow
from a point that had not yet heard is indistinguishable, after the fact, from
an allow by a point that heard and ignored it. The first is propagation
delay. The second violates this spec.
An implementation MUST now define how revocations reach its points, and SHOULD
let each state how current its knowledge is.
Runtime::revocation_known_throughrecords it, defaulting toNone, which anauditor MUST read as unverifiable rather than current — "did not say" is not
"was current".
Stated in the method's own docs rather than left implied: the marker is state
on the enforcement point and the
jcp/2receipt does not carry it, so an auditorneeds it out of band. Binding it into the signed core is the stronger fix and
reaches every
Decisionconstruction site across six standards' referenceimplementations — 75 of them, in workspaces that do not build together — so it is
separate work, not a line in this one.
Verification
jcp-rsworkspace 404 passed. The two clippy warnings injcp-runtimearepre-existing (2 on the baseline, checked against a stash).
Falsifying the marker caught a vacuous assertion of my own. I had written
that declaring a marker changes no decision, and checked it by comparing two
runtimes that both held no revocation — which passes however the marker
behaves. The test now applies a real revocation first, so clearing the
revocation set from the setter is caught.
Two earlier mutation attempts also "passed" because they patched lines that do
not exist:
RuntimederivesDefault, so the marker'sNonecomes byderivation and there is no constructor literal to break.
Some(0))an_unstated_revocation_marker_is_not_a_current_oneMerge order with the sibling PR
#190 adds §4.10 (the flow gate) and this one adds §4.11. They conflict with
each other, though each merges cleanly against main: both insert a new §4.x at
the same anchor, after §4.9 and before §5. Nothing else overlaps —
jcp-orchestrateandjcp-runtimeare disjoint, and neither references theother's symbols.
Merge #190 first. Then rebase this one; the resolution is to keep both
sections in numeric order, which is also the order they must read in: §4.10
Flow, §4.11 Durable spend. I checked the landing by merging the whole set onto
main in a scratch branch — the sequence comes out §4.9, §4.10, §4.11, §5, and
afterwards §4.10 has 13 code references against 1 spec section and §4.11 has 0
against 1.
(A
git merge-treebetween the two branches reported no conflict and I believedit; a real merge disagrees. The textual check was wrong, not the branches.)
🤖 Generated with Claude Code
paths:matches the push delta #191