Skip to content

conformance: JCS number-serialization vectors for the anchored-evidence RFC - #1

Open
lywinged wants to merge 4 commits into
imran-siddique:rfc-anchored-evidencefrom
lywinged:jcs-number-vectors
Open

conformance: JCS number-serialization vectors for the anchored-evidence RFC#1
lywinged wants to merge 4 commits into
imran-siddique:rfc-anchored-evidencefrom
lywinged:jcs-number-vectors

Conversation

@lywinged

Copy link
Copy Markdown

Opening these as a PR as requested on OpenSecureAIAlliance#18, targeting the
RFC branch so the set lands with the document it tests.

Fourteen settled vectors and five pending, plus a runner that points at any
implementation. Settled covers the areas Appendix B does not: the exponent's
leading zero and the thresholds at each end. Expected values agree across three
oracles, rfc8785 0.1.4, V8 22.22.2, and a formatter written independently from
ECMA-262 7.1.12.1, and every settled vector fails at least one of eight plausible
but wrong serializers. The five integer cases assert nothing and stay pending
until the RFC states the allowed number range and the verifier's required
behavior, as agreed on the thread.

The two commits are the ones published on the thread, unchanged from 9324914,
both DCO signed.

…B does not cover

Fourteen settled vectors covering the exponent's leading zero and the
thresholds at each end, verified against three independent oracles: rfc8785
0.1.4, V8 22.22.2 which RFC 8785 section 3.2.2.3 names as a reference
implementation, and a formatter written from ECMA-262 section 7.1.12.1. All
three reproduce the one Appendix B entry available.

Every vector fails at least one of eight plausible-but-wrong serializers. A
vector that no wrong implementation fails is not evidence and was not kept.

Inputs are given as IEEE 754 hex, following Appendix B's own convention, so a
vector does not depend on the parser that reads it.

Five pending cases assert no answer. RFC 8785 defers to ECMA-262, which has one
number type and it is a double, so serializing an integer depends on whether the
implementation converts first. Three behaviours were observed for the same input:
a collision, a divergence between two non-raising implementations, and a refusal.
Raised for the working group on OpenSecureAIAlliance#18.

Signed-off-by: Louielunz <48041247+lywinged@users.noreply.github.com>
…e framing

Two things a fresh clone caught that reading did not.

The runner crashed with KeyError on the fifth pending case, which carries an
observed list rather than a single expect_per_spec. Anyone cloning the branch and
running the documented command hit it. It now handles all three input shapes.

The framing said serializing an integer is not well-defined. Appendix B note 2
settles it: even where an integer like 2**68 could be regarded as having extended
precision, the serialization does not take that into consideration. It is a
double. So there is one conformant answer and it is the one with the collision in
it, which is what note 1's SHOULD on producers exists to guard and why a SHOULD on
producers does not protect a verifier. The two other observed behaviours are
non-conformant rather than alternatives, and the file now says so.

Also removed a reference to another project's schema from a vector's context
field. It was true and checkable, but a finding about someone else's repository
does not belong in a sentence inside this one.

Signed-off-by: Louielunz <48041247+lywinged@users.noreply.github.com>
…ements

Two corrections from review on OpenSecureAIAlliance#18. 2**68 is a power
of two and exactly representable in binary64; what the algorithm changes is the
spelling, and the 4144 is the gap between the shortest round-tripping decimal
and the integer, not a floating-point loss. And 9007199254740992 is 2**53, just
outside the safe range, not inside it; that is exactly why the bound is 2**53 - 1.

The five pending cases settle in a named admission profile, safe-integer-admission,
kept separate from the serialization vectors: a serialization vector says what
bytes RFC 8785 produces, an admission case says whether an evidence profile
accepts the value at all. Twenty cases: the boundary in both signs, 2**53 and
2**53 + 1 and 2**68, the same values spelled with a fraction and in exponent form
and negated, the six settled inputs that serialize correctly and are integer-valued
doubles above the range, three non-integer values the rule does not reach, and negative zero.
Admission is decided on the value, not the token's spelling. The runner checks
both suites and its exit code covers both; the former pending cases are kept as
observations of what shipped serializers do.

Signed-off-by: Louielunz <48041247+lywinged@users.noreply.github.com>
Review on OpenSecureAIAlliance#18 found the two domains disagree just
outside the safe range: 9007199254740991.5 is not an integer as a decimal, so an
exact-decimal check admits it, but it rounds to 9007199254740992 as a double,
which is what JCS serializes, and that value is rejected. An exact-decimal rule
admits an input whose canonical spelling it rejects. The profile now states its
domain: the token is taken as the binary64 value RFC 8785 serializes, non-finite
is rejected, then the integer-valued test and the range apply. The reference
check in the runner does the same.

Seven cases added, twenty-seven in all: four outward-rounding tokens in both
signs and both spellings, rejected; two inward-rounding controls at .25, admitted
under either rule; and 1e999, not finite as a double. The twenty earlier cases
agree under both domains and are unchanged.

Signed-off-by: Louielunz <48041247+lywinged@users.noreply.github.com>
@lywinged

lywinged commented Sep 5, 2026

Copy link
Copy Markdown
Author

Status since 9324914, for whoever reads this PR rather than OpenSecureAIAlliance#18. Two commits are on the branch now, both from review there by DmitrL-dev, in the first review and the second.

  • e2327b2: two corrections to the pending-case text, 2^68 is exactly representable and the 4144 is a decimal-spelling gap, and 9007199254740992 is outside the safe range, not inside; and a second suite, safe-integer-admission, marked proposed and not adopted, so that serializer conformance and profile admission are checked separately. Six of the fourteen settled vectors serialize correctly and are not admissible.
  • 8783ca1: the profile decides on the binary64 value RFC 8785 serializes rather than on the decimal token, after the reviewer showed the two disagree one ulp outside the cases. Twenty-seven cases, every one matching Number.isFinite(v) && (!Number.isInteger(v) || Number.isSafeInteger(v)).

The fourteen settled serialization vectors are byte-for-byte as at 9324914. The five pending cases are now settled inside the admission profile against a candidate range sentence posted on OpenSecureAIAlliance#18, which is proposed text and not the RFC's; the condition of 2026-08-27, that they wait on the RFC stating the range, still stands for the RFC, and the branch now carries what that sentence could be. python run_vectors.py jcs-number-vectors.json runs both suites from a fresh clone and fails on either.

Tool-assisted: the runs and this write-up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant