AI Initiative logoAI Initiative
Reading room / Manthan

@herald/cbor-det — HERALD v0.2 CBOR-deterministic codec

@herald/cbor-det — HERALD v0.2 CBOR-deterministic codec. Covers Install / build; Usage; What gets encoded as what; What strict decode rejects.

Project explanation / technical method
This is the retained source text, not a new validation of its claims. Numerical results and comparative claims require the accompanying source review before public reuse.

Read the connected case study or article →

Not explicitly stated in source · Date not established

Provenance, authorship and editorial notes

@herald/cbor-det — HERALD v0.2 CBOR-deterministic codec

Id

manthan-herald-protocol-lib-cbor-det-readme

Project

Manthan

Source path

manthan/herald-protocol/lib/cbor-det/README.md

Source sha256

9ed244fbd255062f9b6456c17a4697de6aa1a63c3428e1587788f9d3be19832d

Local copy sha256

9ed244fbd255062f9b6456c17a4697de6aa1a63c3428e1587788f9d3be19832d

Repo head

3a94084024a3434cef331fecac91c2c3b43f0313

Date
Not recorded
Date basis

Original publication date not established; Git revision date retained separately.

Author

Not explicitly stated in source

Author basis

Unknown; Git committer not substituted for document author.

Last source commit

8b75d1b0157c20a0a463f0e31008ef9f73099beb

Last source commit date

2026-06-08T07:40:14Z

Document status

Project explanation / technical method

Summary

@herald/cbor-det — HERALD v0.2 CBOR-deterministic codec. Covers Install / build; Usage; What gets encoded as what; What strict decode rejects.

Topics
  • Exploration architecture and selection
  • Install / build
  • Usage
  • What gets encoded as what
Theme

Exploration architecture and selection

Priority

deep

Related ids
  • manthan-readme
  • manthan-docs-architecture
  • manthan-docs-business-overview
  • manthan-docs-demo-walkthrough
  • manthan-docs-principles
  • manthan-docs-qd-measurement-direction-plan
  • manthan-docs-swarm-evolution-integration
Evidence concerns
  • Recovered source text is preserved verbatim. Assertions, comparisons, commands and results belong to its original context; they were not re-executed or externally re-verified during this corpus review.
Word count

676

Bytes

5741

Source relative

herald-protocol/lib/cbor-det/README.md

Remote mirror

manthan/herald-protocol/lib/cbor-det/README.md

Full text preserved

True

@herald/cbor-det — HERALD v0.2 CBOR-deterministic codec

A focused, dependency-free TypeScript implementation of the HERALD
SPEC §3.5 (../../../../SPEC.md) canonicalisation profile, sitting on
top of RFC 8949 §4.2.1
core deterministic encoding.

This is the bytes layer on which T-003 (envelope build/sign/verify) and
everything downstream depends. It produces byte-identical canonical
bytes to worker-A's Python cbor2.dumps(value, canonical=True) output.


Install / build

cd manthan/state/findings/T-002
npm install              # installs typescript + vitest only (zero runtime deps)
npm run build            # tsc → dist/
npm test                 # vitest run
npm run typecheck        # tsc --noEmit

Node ≥ 18 (required for Float32Array, BigInt, TextEncoder /
TextDecoder with fatal: true).

Usage

import { encode, decode, ProfileError } from "@herald/cbor-det";

const bytes = encode({
  v: "herald/0.2",
  ts: 1746432000,
  nonce: new Uint8Array(16).fill(0xaa),
  payload: { hello: "world" },
});

const value = decode(bytes);
// value === { v: "herald/0.2", ts: 1746432000, nonce: Uint8Array, ... }

// Strict mode: any non-canonical byte sequence throws.
try {
  decode(badBytes);
} catch (e) {
  if (e instanceof ProfileError) {
    console.error(e.code, e.message);  // e.g. "E_MAP_ORDER ..."
  }
}

What gets encoded as what

JS inputCBOR major type / encoding
nullSimple(22)
true / falseSimple(21) / Simple(20)
number (integer)mt 0/1, shortest argument
number (float, integer-valued)mt 0/1 (integer-prefer rule)
number (float, fractional)mt 7, shortest of float16/32/64
bigint in [-(2^64), 2^64-1]mt 0/1
stringmt 3, UTF-8 bytes
Uint8Arraymt 2
T[]mt 4
plain object (string keys)mt 5, keys sorted by encoded-key bytes
anything else (Date, Map, Set, class instances, Symbol, function, undefined, ArrayBuffer)ProfileError E_TYPE

What strict decode rejects

Error codeWhat triggers it
E_INDEFINITEindefinite-length items (mt 2/3/4/5 with info=31), break byte
E_NON_MINIMAL_LENlength/integer encoded longer than necessary
E_MAP_KEYmap key not a text string
E_MAP_ORDERmap keys not in canonical sorted order
E_DUP_KEYtwo map entries with identical encoded keys
E_NAN / E_INF / E_NEG_ZEROforbidden float values
E_FLOAT_IS_INTfloat value is an integer (must use integer encoding)
E_FLOAT_WIDEfloat wider than necessary (must use shortest IEEE-754 width)
E_TAGany tag (no Appendix A in v0.2 — see INTERPRETATION.md)
E_UNDEFSimple(23) "undefined"
E_SIMPLEother reserved/unsupported simple values
E_RESERVED_INFOadditional-information value 28/29/30
E_UTF8text string contains invalid UTF-8
E_TRAILINGinput has bytes after a complete top-level value
E_EOFinput truncated mid-value
E_INT_RANGEinteger outside [-(2^64), 2^64-1] (would need bignum tag)
E_TOO_BIGcollection length too large to handle safely

Tests

npm test

Currently:

Test fileCasesWhat it covers
round-trip.test.ts9decode(encode(x)) ≡ x for ints, bigints, strings, byte strings, null, booleans, arrays, envelope-shaped objects, floats
strict-mode.test.ts25hand-crafted non-canonical inputs are rejected with the correct error code
edge-cases.test.ts24encoder rejects NaN/Inf/-0/undefined/Date/Map/Set/Symbol/function/ArrayBuffer/class instance; integer-prefer; float widths; bigint range
vectors-interop.test.ts14byte-identical to test-vectors/v0.2/vectors.json: 7 decode→encode round-trips + 7 build-from-inputs reconstructions (replay-genesis skipped from PART 2 because it carries no inputs of its own)

72 tests pass.

Layout

src/
├── encode.ts     (~280 LoC) canonical encoder
├── decode.ts     (~370 LoC) strict decoder
├── profile.ts    (~110 LoC) SPEC §3.5 constants and ProfileError
└── index.ts      public exports

test/
├── round-trip.test.ts
├── strict-mode.test.ts
├── edge-cases.test.ts
└── vectors-interop.test.ts

Cite

If T-003 (or any later library) needs to encode envelope bodies, import
from this package. The contract is:

returns silently re-canonicalised data.

Continue exploring