A live interop job: this port exchanges bytes with the pinned C++ reference - #5
Merged
Conversation
…erence The port exists to be wire compatible and nothing measured that against the reference itself. The new interop job builds the C++ library at a pinned release and runs it head to head with this port on every push and pull request. interop/interop.cpp and interop/serialize/interop/Interop.java serialize the same boundary message: every operation STANDARD.md defines, at the values where implementations disagree. Zero bit ranges on int, int64, int128 and fixed point; the domain edges of the ranged integers and of int_relative, every tier of its ladder at both ends; the maximum widths of bits, uint128 and the four group fixed point path; both sides of the alignment rule, including the align inside a zero length bytes; empty and full strings; and the wide string cases the surrogate rule governs, up to the largest code point. Floats are given and compared as raw bit patterns, so a value comparison cannot hide -0.0. Both halves write it and the files must be byte identical; each decodes the other's file, checks every value and re-encodes it byte for byte. Then the hostile half: every proper prefix of the other's stream is a truncated stream and both sides must refuse it without throwing, and both sides run the shared conformance corpus, where the refusal vectors are the point. ConformanceTests gains a main so the corpus can be run on its own, which is what lets both sides of that claim live in one job. The reference tag is named in ONE place, SERIALIZE_TAG in the workflow, and the version in one, SerializeUtil.VERSION. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The port exists to be wire compatible, and nothing in this repository measured that against the reference itself. The four ports with a live interop gate (c, cs, go, rs) each run one; this one did not.
What the job does
interopbuilds the C++serializelibrary at the releaseSERIALIZE_TAGpins and runs it head to head with this port, on every push and pull request.interop/interop.cppandinterop/serialize/interop/Interop.javaserialize the same boundary message — every operationSTANDARD.mddefines, at the values where implementations disagree:bitsat 1, 7, 31, 32, 33 and 64, at all-ones and all-zerosboolin both codes;alignwhere it pads and where it must write nothinguint8/16/32/64/128at their domain edges, including the 128-bit all-onesint,int64,int128: degenerate ranges (min == max, zero bits, mid-sequence with a live field after them), both ends of a narrow range, and the full domain at both ends — 32, 64 and 128 bits on the wirefixed: both ends of a Q8.8 range, a degenerate Q16.16, the 34-bit Q48.16 path, the three-group Q112.16 top, a degenerate Q64.64 (zero bits at 128-bit storage) and the four-group Q64.64 topint_relative: every tier of the ladder at both ends, the absolute tier at its smallest difference, and both domain edgesfloat/doubleas bit patterns: ±0, ±infinity, the largest finite, the smallest normal, the smallest subnormalcompressed_float: both range endpoints, the four between-quanta discriminators, a non-zero min, both clamp witnesses, and a one-bit field in both codesbytes: a zero length block from an unaligned position, so the align inside it is load bearingstring: empty, full (15 bytes in buffer size 16), multi-byte UTF-8wstring: empty, basic plane, the first code unit above the surrogate block, the largest code unit, an astral code point as its surrogate pair, and fullThen:
conformance/corpus: the pinned reference reader and this port's reader, same files, same accepts, same refusalsThe Java half honors this port's read allocation contract (
BitReaderrequires eight zero bytes of slack past the data), which is what makes the truncation sweep a test of the missing bits rather than of what follows them.Deliberately not carried: a NaN payload.
STANDARD.md's bit-transparency claim covers it, but NaN payload bits do not survive every language's float type on the way to the wire, so a difference there would say nothing about the wire format. Each port pins its own NaN patterns in its own suite.Two small supporting changes
ConformanceTestsbecomes public and gains amain(), so the corpus can be run on its own (make conformance). That is what lets both sides of the corpus claim live in one job instead of being split across two.Makefilegainsconformanceandinteroptargets, built the same way the tests are: against the library classes only,--release 17 -Xlint:all -Werror, run with-ea.The pin
SERIALIZE_TAG: v1.16.0in.github/workflows/ci.ymlis the one place this repository names a version of the reference; the harness sources name none. The version bump is inSerializeUtil.VERSION(1.1.0 → 1.1.1), with the README's restatement of it kept in step.Verified locally
Against
mas-bandwidth/serializeatv1.16.0on the pinned JDK: byte identical both ways, both re-encodes exact, all 483 truncated prefixes refused on both sides, corpus green on both readers, andmake test/make test-releasestill 110 tests, 2271 checks, 0 failed.Note on the red spec-sync job
The
STANDARD.md ... match upstreamjob is red here, and it is red onmainfor the same reason: upstreammas-bandwidth/serializemovedSTANDARD.mdafter this repository vendored it (#114, then #115). This branch does not touchSTANDARD.mdorconformance/— the vendored copies are byte identical tomain's, and the corpus still matches upstream. Re-vendoring the amended standard, and porting whatever it implies, is its own change.🤖 Generated with Claude Code