How it works in AgenID
Canonicalization runs on a parsed data structure, never by patching serialized text. Members are sorted by UTF-16 code units, non-ASCII text is emitted as raw UTF-8, strings escape only quotation marks, backslashes and control characters, and numbers follow ECMAScript formatting, so 1.0 becomes 1. AgenID adds one rule: NaN, infinity and integer literals above 2^53 minus 1 are rejected as invalid_number_domain, and no schema field is a number at all. The canonical bytes feed both the manifest digest and the Ed25519 signing input.
Why it matters
It is what makes a signature independently re-verifiable. The specification publishes adversarial vectors for numbers, Unicode, sort order and empty values; the browser signer at /issue uses its own independent JCS implementation; and the public conformance suite lets any other implementation check itself.
Without JCS, an innocent difference such as one library writing 1.0 where another writes 1 would change the bytes and break the signature. With it, a verifier in any language reconstructs the exact input the signer used, which is the precondition for checking anything offline.
What it does not mean
Canonical bytes make agreement about what was signed possible; they say nothing about whether it is true. Canonicalization is also not a permission mechanism: it fixes what a statement says, not what an agent is allowed to do. Nor is it encryption: canonical JSON is readable by anyone.