feat(glyph): finish-the-format — contract discipline across Go/Py/JS#12
Merged
Conversation
Land the "finish the format" pass: one normative canonical contract, lossless round-trips in every mode, exact schema semantics, hardened patch + GS1, collision-safe bridges, and full cross-language conformance. Contract & spec (W1): - docs/CANONICAL_FORMS.md, GLYPH_T_SPEC.md, GRAMMAR_MATRIX.md - annotate experimental surface (EmitV2/TokenAware/EncodeDictFrame/Decimal128) Canonical scalar consistency (W2): - bytes b64"..." in every mode (emit+parse); ref quoting via canonRef + quoted ^"..." scanRef; one UTC RFC3339 time form (trimmed fraction); float shortest-round-trip + always a decimal point; NaN/Inf Loose hard-error; conservative bare-string quoting incl. the "_" null token Parser unification (W3): - incremental parser: time/b64 hard-error instead of silent truncation - shared parse_helpers.go (time/quoted-string/\u escape) across modes, fixing \uXXXX control-char corruption in packed/tabular/loose Schema semantics (W4): - Schema.Check() linter; required-null enforcement; ApplyDefaults; @OPEN @unknown capture; constraint-text round-trip fixpoint GS1 + safety (W7): - GS1_SPEC v1.0.1: seq-0 sentinel, error-code registry, hashmode negotiation - split DefaultToolRegistry; dangerous tools require explicit opt-in Patch hardening (W6): - robust path grammar (map-key unescape, list-index errors), panic-free ApplyPatch, VerifyPatchBase, Diff/Apply round-trip invariant Cowrie bridge (W5): - $glyph reserved-marker + exact-shape guards; fix _type/_tag/^-string collisions and the "type"-field silent-loss bug Cross-language finish (W8): - mirror Python + JS to the contract; re-pin the shared corpus - 21/21 Go/Py/JS parity; Go light gate green; contractcheck 104/104; pytest 433 passed (5 xfail: JSON int/float bridge boundary); jest 514 passed Test infra: gate the memory-heavy bomb/benchmark tests behind //go:build heavy so the default `go test` gate stays light; CI runs the full suite nightly with -tags heavy. Add cmd/contractcheck and cmd/bridgecheck (library-only checkers). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…incremental safety
All four code-review findings fixed and verified (contractcheck 137/137,
all-impl parity 24/24, pytest 433, jest 514, Go light gate green):
1. Float canonical parity (parity-breaking): Python (loose.py) and JS (loose.ts,
codec_primitives.ts) now byte-match Go strconv.FormatFloat('g',-1,64) —
exponential iff decimal-exp <= -5 or >= 6, 2-digit padded exponent. The
magnitude exponent is derived from the shortest decimal digits, NOT
math.log10 (which rounds the wrong way just below a power of ten, e.g.
999999999999999.8 -> 9.999999999999998e+14). Verified vs a 1503-value Go
reference + boundary set with zero mismatches.
2. JS ref quoting (parity-breaking): canonRef quotes ^"ns:a:b" when the value
contains ':' (mirrors Go/Python), instead of a bare ^ns:a:b that mis-splits.
3. Incremental parser (silent corruption): parseRef handles quoted ^"..." refs
(or cleanly awaits-more) instead of silently emitting an empty RefID —
closes the silent-truncation gap W3 left for refs. + tests.
4. JS typed canonFloat: NaN/+Inf/-Inf emit bare tokens NaN/Inf/-Inf, not
"NaN.0"/"Infinity.0".
Corpus: large-float and ':'/'/'-in-value ref vectors added to the contract
fixtures and the cross-impl parity gate so this class is now covered.
Cleanups: remove now-dead isBareSafeV2; dedup the b64 decode block into
parse_helpers.decodeBytesLiteral (packed + tabular).
Co-Authored-By: Claude Opus 4.8 <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
The "finish the format" pass from the strategic review: **one normative canonical
contract, lossless round-trips in every mode, exact schema semantics, hardened patch
claim was ground-truthed against
mainfirst (several were stale and skipped).What shipped
docs/CANONICAL_FORMS.md,GLYPH_T_SPEC.md,GRAMMAR_MATRIX.md; experimental surface annotatedb64"…"in every mode (emit+parse); ref quoting (canonRef+ quoted^"…"scanRef); one UTC RFC3339 time form (trimmed fraction); float shortest-round-trip + always a decimal point; NaN/Inf Loose hard-error; conservative bare-string quoting incl. the_null tokenb64instead of silently truncating; sharedparse_helpers.go— fixes\uXXXXcontrol-char corruption in packed/tabular/looseSchema.Check()linter; required-null enforced;ApplyDefaults;@open@unknowncapture; constraint-text round-trip fixpointhashmode);DefaultToolRegistrysplit soexecute/read_file/write_filerequire explicit opt-inApplyPatch,VerifyPatchBase,Diff/Applyround-trip invariant$glyphreserved-marker + exact-shape guards; fixes_type/_tag/^-string collisions and thetype-field silent-loss bugVerification
TestGoldenFiles+TestCrossImplafter re-pin)parse(emit(x))==x, identical fingerprints across Go/Py/JS) now hold for real.Test infra
The memory-heavy bomb/coverage/benchmark tests are gated behind
//go:build heavy, so thedefault
go testgate stays light; CI runs the full suite nightly with-tags heavy.Added
cmd/contractcheckandcmd/bridgecheck(library-only conformance checkers).Known caveats / carry-forward (none are canonical-form bugs)
-0→int in Go, float in Python). A separate concern from canonical form; documented as xfail.
SortOpsorders FID/list-index ≥10 lexicographically (opt-in sort, low-impact).DefaultToolRegistryis deprecated, not removed (back-compat).ApplyDefaultsdoesn't recurse into nested structs;@unknowndecode-back deferred.hashmodereader-parsing is spec-committed but not yet wired;StateHashEmitlacks aDeprecatedgodoc.\udecoding doesn't handle surrogate pairs (pre-existing).🤖 Generated with Claude Code