v0.2.0: adversarial hardening — uniform rejection contract across all 7 lineages - #1
Merged
Conversation
…-data conformance - Plain-decimal number domain in all 7 CLIs (lexical): no exponent tokens, integers limited to [-2^53, +2^53] by digit-string compare, fractions in [1e-6, 1e21). '100' accepted, '1E2' rejected. - ES-262 ToString float formatting in every lineage (shortest round-trip, plain decimal, zero -> "0"): C/OCaml %.*e+strtod loop, C++ to_chars, Rust std Display, D %.*e loop, Haskell floatToDigits. The whole fraction band [1e-6, 1e21) is now byte-identical across all seven. - Go: lone-surrogate escapes rejected (backslash-run parity), -0.0 -> "0". - OCaml: lone LOW surrogate rejected (yojson only caught the high half). - D: strict single-document parse (trailing garbage, concatenated docs, trailing comma, empty input all rejected; std.json accepted all four). - C/C++: leading UTF-8 BOM rejected. C++: over-uint64 integer tokens rejected (nlohmann routes them to number_float). - Corpus-as-data: conformance/accept.jsonl (23 pinned) + reject.jsonl (19) generated by gen_corpus.py, which refuses to pin divergent cases; verify_all_lineages.sh is corpus-driven; differential_probe.py sweeps 165 generated danger-zone cases in CI (agreement-only). - CI: actions pinned to commit SHAs; package versions -> 0.2.0; README states the precise domain (closed interval +/-2^53, plain-decimal floats, single-document rule) and prerequisites. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… controls, lax tokens; ES-262 shortest-digits fix Third conformance layer added: conformance/fuzz_agreement.py, a seeded randomized fuzzer (structured boundary-biased documents, byte mutations of valid documents, raw garbage) asserting seven-way agreement per input. Campaign seed 20260715, 8000 cases: initially 82 failures, now 0. Divergence classes closed (all lexical pre-parse checks; cores untouched): - invalid UTF-8 (stray continuation, truncated, overlong, encoded surrogate, >U+10FFFF): C/D/OCaml accepted verbatim, Go replaced with U+FFFD and hashed the replacement (silent cross-lineage collision) — now rejected in all 7 - raw control bytes in string literals (C, and pinned in Haskell/OCaml); non-whitespace control bytes between tokens (C skipped <=0x20; D skipped VT/FF via isWhite) — JSON whitespace is only TAB/LF/CR/space - number-token grammar: leading zeros (C, D), bare trailing dot (C), junk attached to number tokens '2-' (D) - malformed backslash-u escapes with <4 hex digits (C) - case-insensitive literals nuLl/falSe (D); unquoted keys, // and /**/ comments, NaN/Infinity/-Infinity (OCaml/yojson) - HASH SPLIT (worst class): Haskell emitted 17-digit exact value instead of ES-262 shortest digits for even-mantissa boundary doubles beyond 2^53 (GHC floatToDigits uses open-interval comparisons); shortening pass added, latent exact-integer fast path at 2^53-adjacent .0 tokens removed Corpus grown to 24 accept (pins big-float shortest-digits) + 31 reject rows; differential probe grown to 234 deterministic cases (raw-byte payload support for invalid-UTF-8 cases); README domain contract updated. Co-Authored-By: Claude Fable 5 <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.
Summary
Hardening round driven by the new 3-layer conformance stack (pinned corpus, deterministic differential probe, seeded adversarial fuzzer). The first 8,000-case fuzz campaign found 82 agreement failures that the corpus, probe, and four GPT review rounds had all missed; every one is closed here.
Breaking change: v0.2.0 rejects inputs v0.1.3 accepted. The accepted domain is now strictly narrower and uniform across all seven lineages:
Verification
🤖 Generated with Claude Code