Canonical serialization is the mechanism that makes every hash, signature, and fingerprint in the governance pipeline reproducible across languages, platforms, operating systems, and time. Without it, the same data produces different bytes on different systems - and different bytes produce different signatures, different fingerprints, and broken verification. Every guarantee in Parmana - deterministic decisions, portable verification, replay protection, independent auditability - depends on canonical serialization being correct.Documentation Index
Fetch the complete documentation index at: https://docs.manthan.systems/llms.txt
Use this file to discover all available pages before exploring further.
Why ordinary JSON serialization fails
StandardJSON.stringify() in JavaScript does not specify key ordering. Different engines, different insertion orders, and different serialization libraries may produce different byte sequences for logically identical objects:
What canonical serialization requires
Parmana’scanonicalize() function resolves this by producing a stable, deterministic byte sequence from any input:
Sorted keys - all object keys are sorted recursively at every nesting level:
é can be encoded as a single code point U+00E9 or as e + combining acute accent U+0301. After NFC normalization, both become the single code point, producing identical bytes.
CRLF normalization - Windows-style \r\n line endings are converted to Unix-style \n before serialization. A policy file edited on Windows and a policy file edited on Linux produce the same canonical form.
Preserved array order - array element order is semantically meaningful and must not be sorted. Policy rules, for example, are evaluated in declaration order - reordering them would change governance outcomes.
Where canonical serialization is used
Every cryptographic operation in the governance pipeline uses canonical serialization:| Operation | What is canonicalized |
|---|---|
execution_fingerprint derivation | Input signals |
| Token signing | The full ExecutionToken object |
| Attestation signing | The attestation payload |
| Bundle manifest hashing | Policy files |
| Runtime manifest hashing | The runtime manifest definition |
| Release manifest signing | The release manifest |
canonicalize() function is used throughout. There is no variant implementation with different behavior - any divergence would produce different bytes and break verification.
The fingerprint depends on canonical form
Theexecution_fingerprint is the replay protection key:
canonicalize() sorts keys, any two requests with logically identical signals produce identical fingerprints - regardless of key insertion order, JavaScript engine, or platform:
The signature depends on canonical form
The Ed25519 signature is computed over the canonical byte representation of the payload:valid would be false even for a legitimate attestation. One canonical implementation is the invariant.
What breaks without canonical serialization
| Failure | Consequence |
|---|---|
Multiple canonicalize() implementations with different behavior | Signing and verification use different bytes - all signatures fail |
| No Unicode NFC normalization | é as U+00E9 and é as U+0065+U+0301 produce different hashes - same content, different fingerprints |
| Order-dependent key serialization | Two requests with the same signals produce different fingerprints - replay not detected |
| CRLF not normalized | A policy edited on Windows has a different bundle hash than the same policy on Linux - bundle verification fails |
| Pretty-printing vs compact | Signing with spaces, verifying without - signature fails |
Canonical serialization across the ecosystem
Because canonical serialization uses standard sorted JSON with NFC-normalized strings, any implementation - in any language - can produce the same bytes given the same input. A verifier written in Python, Go, or Java can verify a Parmana attestation produced by the TypeScript runtime, provided it implements the same canonicalization rules. This is what makes portable verification possible. The canonical form is the shared language between the signer and any verifier, across all implementations.The @parmanasystems/bundle package
The canonical serialization implementation lives in @parmanasystems/bundle:
@parmanasystems/governance, @parmanasystems/verifier, and @parmanasystems/execution. Consuming it directly is rarely necessary for application code.
See also
- Trust Portability - how canonical serialization enables portable signatures
- Governed Signals - how signals are canonicalized for fingerprinting
- Portable Verification - independent verification across platforms
- Bundle Package - the canonicalize and sha256 implementations