pub fn frame_commitment(provider_id: &str, frame: &ContextFrame) -> [u8; 32]Expand description
The commitment binding one frame’s identity to its provenance chain
(SPEC.md §6.5.2) — the preimage a single-frame attestation signs.
SHA256(
domain::FRAME ‖ enc(provider_id) ‖ enc(frame.id)
‖ enc_opt(frame.content_digest) ‖ chain_head
)content_digest is included so that, when the frame declares one,
the signature covers the frame’s bytes and not merely its name.
When the frame declares none, it does not. enc_opt writes a single
0x00 presence byte, so the preimage records the absence honestly
rather than substituting a placeholder — but what gets signed is then
identity and provenance alone, and a provider can re-serve entirely
different content under the same frame id with that signature still
checking out. The encoding is doing its job; the guarantee is simply
narrower than the presence of a signature suggests.
Two things follow, and both are load-bearing (#128):
SPEC.md§6.5.2 requires a provider that signs a frame to populatecontent_digest. A digest-less frame remains conformant; signing one is not. This function still computes the commitment for such a frame, because a verifier has to be able to check signatures produced before that rule, or by an implementation that ignores it.verify_frame_attestationreturnsAttestationVerdict::ValidIdentityOnlyrather thanAttestationVerdict::Validfor exactly that case, so no caller can mistake the narrower guarantee for the wider one.
A frame that declares no digest and carries no attestation is a
different thing again: unverifiable by design
(docs/context-reuse.md §4), and no rule here applies to it.