prereg_seal
prereg-seal — seal an acceptance specification before you measure.
Raised when a specification does not match the seal presented with it.
Deterministic bytes for any JSON-serializable specification.
Sorted keys, no insignificant whitespace, UTF-8, and NFC-normalised strings. Two specifications that differ only in key order, formatting, or Unicode normalisation form produce identical bytes; two that differ in any value do not.
Note that JSON has no tuple type, so [1,2] and (1,2) canonicalise
identically — by design, since they serialise identically.
Domain-separated SHA-256 over the canonical form.
Produce a seal artifact for spec.
The seal deliberately does not contain the specification. It contains the digest. Publishing the seal therefore commits you to the criteria without revealing them, which is what makes it usable before a blind evaluation.
Raise SealMismatch unless spec matches sealed.
Both directions fail loudly: altering the specification after sealing
changes the recomputed digest, and altering the seal to match an altered
specification is caught by whatever binds the seal (see bind()).
Boolean form of verify().
Attach a seal to a result record, and cross-bind the pair.
The cross-binding is what makes the second failure direction detectable:
swapping in a seal that matches doctored criteria changes seal_binding,
because the binding covers the result and the seal together.
Verify a bound result end to end: binding intact and spec matches seal.
Seal spec and write the artifact to path.
Fail-closed guard for use at evaluation time.
Re-serializes the specification actually in force, recomputes its digest and compares it to the seal on disk. Raises unless they match.
If the seal file is absent this raises too — an unsealed evaluation is the condition the tool exists to prevent. Set the escape-hatch environment variable only for local exploration; it is deliberately verbose to type and is reported in the returned record so it cannot pass unnoticed.
Build an unverified anchor record.
It is unverified on purpose. Creating the record proves nothing; only
verify_anchor() does, and only by going and looking.
Check the digest really is where the record says, and when.
fetch(url, timeout) -> text can be supplied to test this without a
network, or to route through your own client. With allow_network=False
and no fetch, the result is UNANCHORED — never an accepted claim.
A human-readable line that does not overstate what was established.
A malformed anchor record or locator.
Metadata for an outcome. An unrecognised one is a failure, never a pass.