Skip to content

feat(canonical): JCS (RFC 8785) canonical JSON, verified against ijson-jcs; the KYAML ratchet - #158

Merged
hyperpolymath merged 4 commits into
chore/root-completionsfrom
feat/canonical-jcs
Oct 15, 2026
Merged

hyperpolymath merged 4 commits into
chore/root-completionsfrom
feat/canonical-jcs

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

What this adds

MetaManifold.Canonical — jcs_bytes(x) and jcs_sha256(x): the deterministic byte form of a JSON-shaped value for hashing, signing and content-addressing, per RFC 8785. Object keys sort by UTF-16 code unit (so an astral-plane key sorts before a high-BMP key — the trap naive code-point ordering misses); Float64 values serialize per ECMAScript's Number::toString (shortest round-trip digits, positional between 1e-6 and 1e21, a signed exponent outside it, -0.0 collapsing to 0); integers outside I-JSON's exact range and NaN/Inf are refused, as no consumer reads them back as the same value.

The oracle is the estate's own ijson-jcs crate (Rust, RFC 7493 + RFC 8785): the eleven cases in test/fixtures/jcs_oracle.jsonl were produced by that crate, and test_canonical.jl asserts this implementation reproduces every one byte-for-byte — including the ES number table (4.50→4.5, 2.4499999999999998e16→24500000000000000, 1e30→1e+30, 1e-6→0.000001, 1e-7→1e-7, 1e20 positional but 1e21 exponential, subnormals, -0.0→0), string escaping, and the astral-sort case. Plus hand-written testsets: key-order irrelevance, the refusals, and the content-address property — a chart spec built in any key order hashes identically.

KYAML (YAML-POLICY Y-3): the standards repo's kyaml-format.sh is adopted verbatim, and a ratchet testset runs it --check over every tracked *.kyaml. Per the policy's own decided scope (D280/D307): tool-named files (workflows, dependabot.yml, codecov.yml) keep their extensions, and the shared config defaults convert as an upstream unit, not unilaterally — this repo's YAML is upstream-shared or tool-named, and the policy calls unconverted files backlog, not violations. New estate-owned YAML config in this repo is written as .kyaml from now on; this gate holds it to form.

This is the first slice of the ijson-jcs adoption plan: the writer and the differential-oracle verification. Wiring canonical hashes into attestation.yml and the analysis routes is deliberately not in this slice — those are upstream-shared files, and the change deserves upstream discussion (and possibly as a unit) before the fork diverges there.

Verification

22/22 in test_canonical.jl; 285/285 with the pin suite alongside. The corpus was generated by building ijson-jcs and running each case through it (JsonMode::Strict — the corpus generation itself caught an out-of-range integer the crate correctly refused).

Notes

Stacked on #157 (chore/root-completions) because both touch test_install_pins.jl; rebase onto main once that lands. The commit is signed.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe vibe@mistral.ai

…estate's ijson-jcs crate; the KYAML ratchet

src/canonical.jl adds MetaManifold.Canonical -- jcs_bytes(x) and
jcs_sha256(x) -- the deterministic byte form of a JSON-shaped value for
hashing, signing and content-addressing: object keys sorted by UTF-16
code unit (so an astral-plane key sorts before a high-BMP key, the trap
naive code-point ordering misses), Float64 values serialized per
ECMAScript's Number::toString (shortest round-trip digits, positional
between 1e-6 and 1e21, a signed exponent outside it, -0.0 collapsed to
0), integers outside I-JSON's exact range and NaN/Inf refused as no
consumer reads them back as the same value.

The oracle is the estate's ijson-jcs crate (Rust, RFC 7493 + RFC 8785):
the eleven cases in test/fixtures/jcs_oracle.jsonl were PRODUCED by that
crate, and test_canonical.jl asserts this implementation reproduces
every one byte-for-byte -- key sorting including the astral case, the
ES number table (4.50, 2.4499999999999998e16, 1e30, 1e-6, 1e-7, 1e21,
1e20, subnormals, -0.0), string escaping, nesting, literals -- plus
hand-written testsets for key-order irrelevance, the refusals, and the
content-address property (a chart spec built in any key order hashes
identically). Verified 22/22.

KYAML (YAML-POLICY Y-3): the standards repo's kyaml-format.sh is
adopted verbatim, and a ratchet testset runs it --check over every
tracked *.kyaml. Tool-named files keep their extensions per D307, and
the shared config defaults convert as an upstream unit rather than
unilaterally -- this repo's YAML is upstream-shared or tool-named, and
the policy's own sequencing calls unconverted files backlog, not
violations. New estate-owned YAML config is written as .kyaml from now
on, and this gate holds it to form.

Stacked on #157 (the root-completions PR); rebase onto main once that
lands.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
@coderabbitai

coderabbitai Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: d0bf49d7-48fc-455d-9c9a-bab6a0abc4a3

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sonarqubecloud

Copy link
Copy Markdown

@hyperpolymath
hyperpolymath merged commit e0bf75b into chore/root-completions Oct 15, 2026
10 checks passed
@hyperpolymath
hyperpolymath deleted the feat/canonical-jcs branch October 15, 2026 16:11
hyperpolymath added a commit that referenced this pull request Oct 15, 2026
…n-jcs; the KYAML ratchet (#159)

## What this adds

**`MetaManifold.Canonical`** — `jcs_bytes(x)` and `jcs_sha256(x)`: the
deterministic byte form of a JSON-shaped value for hashing, signing and
content-addressing, per RFC 8785. Object keys sort by UTF-16 code unit
(an astral-plane key sorts *before* a high-BMP key — the trap naive
code-point ordering misses); Float64 values serialize per ECMAScript's
`Number::toString` (shortest round-trip digits, positional between 1e-6
and 1e21, a *signed* exponent outside it, `-0.0` collapsing to `0`);
integers outside I-JSON's exact range and NaN/Inf are refused, as no
consumer reads them back as the same value.

**The oracle is the estate's own `ijson-jcs` crate** (Rust, RFC 7493 +
RFC 8785): the eleven cases in `test/fixtures/jcs_oracle.jsonl` were
*produced by that crate*, and `test_canonical.jl` asserts this
implementation reproduces every one byte-for-byte — the ES number table
(`4.50`→`4.5`, `2.4499999999999998e16`→`24500000000000000`,
`1e30`→`1e+30`, `1e-6`→`0.000001`, `1e-7`→`1e-7`, `1e20` positional but
`1e21` exponential, subnormals, `-0.0`→`0`), string escaping, and the
astral-sort case. Plus hand-written testsets for key-order irrelevance,
the refusals, and the content-address property.

**KYAML (YAML-POLICY Y-3):** the standards repo's `kyaml-format.sh` is
adopted verbatim, and a ratchet testset runs it `--check` over every
tracked `*.kyaml`. Per D280/D307: tool-named files keep their
extensions, and the shared config defaults convert as an **upstream
unit**, not unilaterally — this repo's YAML is upstream-shared or
tool-named, and the policy calls unconverted files backlog, not
violations.

This is the first slice of the ijson-jcs adoption: the writer and the
differential-oracle verification. Wiring canonical hashes into
`attestation.yml` and the analysis routes is deliberately **not** here —
those are upstream-shared files and deserve upstream discussion first.

## Verification

- Full local run before the split: 22/22 in `test_canonical.jl`, 285/285
with the pin suite.
- The module standalone (this session's local R toolchain expired before
this PR was cut): all 11 oracle cases byte-identical, astral case OK,
content-address hash computed — CI's `Julia tests` (which installs the
pinned R) is the full-suite authority.

## Notes

This is #158 rebuilt on `main`: #157's merge auto-closed the stacked
original, and the single commit's tree is byte-identical to it. The
commit is unsigned — the shared signing agent died mid-session (the
fragility the launcher's `--agent` mode exists to fix; its `ssh-add`
step needs the passphrase interactively).

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>

Co-authored-by: Mistral Vibe <vibe@mistral.ai>
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