Commitment contracts

September 3, 2026 ยท View on GitHub

New commitment-bearing code imports named profiles and schema identifiers from legalforecast.contracts.

This Cycle 1 surface characterizes existing byte contracts; it does not migrate existing producers, verifiers, cards, fixtures, or persisted digests.

Named byte profiles

NameBytesIntended use
ARTIFACT_CANONICAL_JSON_V1Key-sorted compact UTF-8 JSON with a trailing newlineWhole JSON artifacts
ARTIFACT_JSON_VALUE_V1Key-sorted compact UTF-8 JSON without a trailing newlineJSON values embedded in another byte stream
MANIFEST_CANONICAL_JSON_V1Key-sorted compact ASCII-escaped JSON without a trailing newline and with the historical default=str behaviorManifest and freeze hashing
RUN_CARD_INDENTED_JSON_V1Key-sorted, two-space-indented ASCII-escaped JSON with a trailing newlineRecovery-slice run cards and policy artifacts that already persist this form

The blessed entry points reject non-finite numbers before serialization.

The artifact profiles delegate to legalforecast.ingestion.canonical_json; the manifest profile delegates to legalforecast._canonical.canonical_json, so valid Cycle 1 payloads retain their exact bytes.

Digest representation and domain

Use ARTIFACT_RAW_SHA256_V1, ARTIFACT_PREFIXED_SHA256_V1, MANIFEST_RAW_SHA256_V1, or RUN_CARD_RAW_SHA256_V1 rather than choosing a serializer and prefix ad hoc.

Each commit call requires a SchemaIdentifier domain and returns a Commitment that retains the profile name, schema domain, and a typed RawSha256 or PrefixedSha256 value.

Verification rejects a commitment from a different byte profile, schema domain, or persisted digest representation before comparing the digest.

The schema domain is an API-level binding and does not add new bytes to historical SHA-256 inputs; changing the digest input would be a versioned migration outside Cycle 1.

Adding a distinct profile

A genuinely distinct persisted representation is allowed only when its byte behavior or digest representation differs and callers need that difference.

Give it a new versioned profile name, characterize Unicode, non-finite numbers, whitespace and newline behavior with literal golden vectors, and document why an existing profile is not correct.

Do not create a universal serializer or silently normalize raw and sha256:-prefixed fields.