diff --git a/src/v1/stage0/src/v1_interpreter.rs b/src/v1/stage0/src/v1_interpreter.rs index 717f572b168..e2be3a600bd 100644 --- a/src/v1/stage0/src/v1_interpreter.rs +++ b/src/v1/stage0/src/v1_interpreter.rs @@ -7903,6 +7903,31 @@ fn rest_uri_value(url: &str, ctx: &InterpContext) -> InterpResult { }) } +/// Seed bridge for the `.dag`-owned `ContentHash` family carrier. REST input identity is +/// the structural FNV-1a digest produced by `content_hash_service_inputs`; the interpreter +/// must realize that modeled value, not leak its wire string across the typed dispatch seam. +/// +/// This is the model↔realization fork DESIGN's open threads name: `#7480` made `ContentHash` +/// a coproduct in `.dag` while this site kept minting the pre-#7480 branded string, so a +/// fixture invocation built in `.dag` could never equal one built here. Every +/// `rest_exchange_replay` witness that requires a fixture to MATCH failed; the ones requiring +/// no match passed, which is the signature of an equality that is always false rather than of +/// a broken lookup. Recovered from the closed PR #7650, which had this right. +/// +/// DISSOLVE-ON: REST service dispatch is evaluated by the emitted transport handler and this +/// host-side `RestBoundOperationInvocation` construction is deleted. +fn rest_structural_content_hash_value(digest: String, ctx: &InterpContext) -> Value { + let structural = Value::Record { + type_name: ctx.sym("Fnv1a64Structural"), + fields: Rc::new(sorted_fields(vec![(ctx.sym("digest"), Value::Str(digest))])), + }; + Value::Variant { + type_name: ctx.sym("ContentHash"), + variant_name: ctx.sym("Fnv1a64"), + fields: Rc::new(vec![(ctx.sym("0"), structural)]), + } +} + fn rest_bound_invocation_value( service_node: &Rc, op_node: &Rc, @@ -7924,7 +7949,10 @@ fn rest_bound_invocation_value( (ctx.sym("at"), at), (ctx.sym("method"), rest_variant(ctx, "HttpMethod", method)), (ctx.sym("target"), rest_uri_value(url, ctx)?), - (ctx.sym("input_digest"), Value::Str(input_digest)), + ( + ctx.sym("input_digest"), + rest_structural_content_hash_value(input_digest, ctx), + ), ( ctx.sym("auth_identity"), rest_auth_identity_value(auth, basic_header, ctx),