Expand description
v0.177 (#643): the canonical normal form of a cross-context contract, and its hash.
A workers build compiles context A against context B’s contract, and
nothing at runtime checks that the deployed B still matches what A was
compiled against — deploy --context NAME institutionalises the skew. The
fix is to stamp a hash of the compiled contract beside X-Bynk-Caller and
fail closed on mismatch (ADR 0092’s pattern: a compile-time constant in a
reserved header, metadata beside the payload, no crypto).
The hash is only as good as the form it hashes. Two rules make it usable:
- Semantically-equal contracts must hash equal, or a working deployment 409s spuriously — which is worse than no check at all, because it breaks what worked and destroys trust in the mechanism. This is why the form is canonical (predicates as a sorted set, record fields sorted by name) rather than a rendering of source order.
- Both sides must canonicalise the same thing. The callee’s contract
is canonicalised in the callee’s own namespace, from the callee’s own
type table, on both sides — never in the caller’s. The caller reaches
that table through
consumed_types[callee]and the callee through its own combined table; both are produced by the samecombined_types_for, so the two views cannot diverge by construction. A caller never canonicalises a consumed type in its own namespace, where its rebranding would make the same type render differently.
Functions§
- canon_
predicate - canon_
refinement - Predicates canonicalise as a sorted set.
- contract_
hash - FNV-1a (64-bit) over the canonical form, rendered as 16 lowercase hex chars.
- service_
contract_ hash - The stamped contract hash for one consumed service.
- service_
normal_ form - The canonical normal form of one
on callservice contract.