Skip to content

feat: Codex v0.4 contract (JCS vectors at 8299fee) - #1

Merged
alexy-os merged 1 commit into
mainfrom
grok/codex-v04-contract-0137
Oct 25, 2026
Merged

alexy-os merged 1 commit into
mainfrom
grok/codex-v04-contract-0137

Conversation

@alexy-os

Copy link
Copy Markdown
Member

Bring github.com/fastygo/codex to Codex data contract v0.4, byte-compatible with @ui8kit/contract 0.2.0 at commit 8299fee (parent 867eb06).

Do not merge-tag v0.4.0 from this PR. Tag only after the contract owner confirms the official vectors.

Official vectors (codex-entry/v1)

Pinned at conformance/contract/ (VERSION commit 8299fee). The published file has 24 cases: 15 ok, 9 error (the request said 17/7; this table follows the actual file). Go matches canonical + digest, or the exact error code, on every case. No divergences to send back.

# Case Result
1 control: post-1/en-US with metadata.price PASS (digest d7ebf2ee…cc4a)
2 key order: reversed top level, whitespace and newlines PASS (9c71a088…96eb)
3 key order: nested in metadata value, UTF-16 order puts U+FF5E before an astral key PASS (d68d38dc…bfe3)
4 strings: quote, backslash, newline, U+001F, solidus PASS (0cf19364…538f)
5 strings: <>& U+2028 U+2029 emoji and Cyrillic stay unescaped PASS (73d79493…d4c9)
6 numbers: 1250 4.5 0.1 12.50 1e21 1e-7 -0 -1250 9007199254740991 PASS (c578a2a9…2ad9; 1e21 → 1e+21)
7 numbers: 9007199254740993 is an unsafe integer PASS canonical.unsafe_integer
8 numbers: -9007199254740992 is an unsafe integer PASS canonical.unsafe_integer
9 empty optional top-level fields are omitted, metadata values are kept PASS (940b35fa…fe75)
10 metadata private:true is removed, private:false is dropped PASS (d7ebf2ee…cc4a)
11 metadata with only private items is omitted PASS (9c71a088…96eb)
12 dates: +03:00 offset is converted to Z, .000Z is dropped PASS (c03a841c…a512)
13 dates: fractional seconds .5Z PASS canonical.fractional_seconds
14 dates: date without time PASS canonical.invalid_date
15 terms are sorted by (taxonomy, term_id) in code point order PASS (aaa00b45…4c37)
16 origin keeps its order PASS (3e8f0b66…8e53)
17 unknown top-level field PASS canonical.unknown_field
18 duplicate key PASS canonical.duplicate_key
19 duplicate key inside a metadata value PASS canonical.duplicate_key
20 non-ASCII id PASS canonical.invalid_id
21 missing locale PASS canonical.missing_field
22 PHP trap: {} in a json metadata value stays {} (not []) PASS (915cb2fb…e495)
23 PHP trap: object with keys "0","1" stays an object PASS (da511da9…7f47)
24 order 0 and pinned false are kept (not empty values) PASS (fb8a8e68…2ef5)

Runner: canonical.Canonicalize / Digest against conformance/contract/fixtures/vectors/canonical.json.

JCS implementation

canonical/ is a local RFC 8785 port of @ui8kit/contract src/canonical.ts + docs/canonical.md (profile draft v0.4, including the codex-manifest/v2 paragraph). No third-party JCS library. encoding/json is not used for canonical output (it HTML-escapes <>& and \u-escapes U+2028/U+2029). Strict parser rejects duplicate keys and unsafe integers before float64.

Manifest.Digest stays codex-manifest/v1 (Go encoding/json of Canonical()). Manifest.DigestV2 is codex-manifest/v2:sha256: over JCS of Canonical().

Contract decisions vs Go

Topic Decision Go
Profile RFC 8785 JCS over public projection canonical package
Private metadata drop private:true; omit private:false matches vectors 10–11
Sensitive Entry v0.4 has no sensitive; profile removes nothing on that basis canonical does not strip; Resource.PublicProjection still does for the Go API
Optional empty omit top-level null/""/[]/{}; keep metadata.<k>.value vector 9
Dates YYYY-MM-DDTHH:MM:SSZ; offsets → Z; .000 dropped; non-zero fraction errors vectors 12–14
Terms / origin terms by Unicode code points; origin keeps order vectors 15–16
Numbers ES Number.toString; -0→0; 1e21→1e+21 vector 6
Q2 unsafe integer reject |n| > 2^53-1; 9007199254740993.0 → unsafe_integer vectors 7–8; article fixture uses 9007199254740991
Q7 localized means translatable; chrome always localized (no flag); entry.localized_mismatch validate.CollectionV04
Q8 id opaque ASCII ^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$ on id only, not *_id; integer PK <kind>-<n> Go Validate + canonical; vendored entry.schema.json left as \S
Q9 money safe integer minor units; negatives allowed; no min; one ISO 4217 currency per record schema.CheckMoneyCurrency
Unknown rules error schema.field.rule_unknown ValidateFieldProfile
Error order json → unknown → missing → id → fields canonical.project
null in required canonical.missing_field required-field loop
order:0 / pinned:false kept vector 24

Pending questions

None for this pin. Q2/Q7/Q8/Q9 are implemented as decided. If a later official vector disagrees, send the case name and Go output back to the contract owner — currently there is nothing to send.

Other v0.4 surface

  • Record key (id, locale); chrome is a string; LocalizedText / Locales removed; status adds pending; origin / discussion / order / pinned / format.
  • Term + taxonomy label are string + locale; revisions bind (entry_id, locale).
  • validate.CollectionV04 ports ISSUE_CODES_V04.
  • migrate.EntryJSON / TaxonomyJSON convert v0.3 → v0.4 for a requested locale and reject unsafe integers.
  • Vendor refresh: scripts/refresh-ui8kit-contract.sh.
  • CI: go test -race.

Verify locally: go test -race -count=1 ./..., go vet ./..., gofmt -l . clean.

Open in Web Open in Cursor 

Bring types, validation, money, and canonicalization to the
@ui8kit/contract 0.2.0 profile at commit 8299fee. Vendor the 24
codex-entry/v1 vectors and pass them byte-for-byte.

Co-authored-by: AlexY OS <alexy-os@users.noreply.github.com>
@alexy-os
alexy-os merged commit 5a6d6e4 into main Oct 25, 2026
2 checks passed
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.

2 participants