Skip to content

test: lock canonical request-hash contract for image-studio edits#92

Closed
adambalogh wants to merge 1 commit into
claude/nifty-knuth-DgpW8from
claude/jolly-hypatia-4BrYt
Closed

test: lock canonical request-hash contract for image-studio edits#92
adambalogh wants to merge 1 commit into
claude/nifty-knuth-DgpW8from
claude/jolly-hypatia-4BrYt

Conversation

@adambalogh
Copy link
Copy Markdown
Contributor

Stacked on top of #82 (Secure attachments).

Context

The chat-app Image Studio's "edit the last image" flow was throwing errors whenever there was an image in the history: the prior generation was inlined into the message content string as a base64 markdown image, so the gateway forwarded it to the model as a giant text prompt (which the provider rejects) instead of as an actual image. The fix is to send the image as a native image_url content part — which is exactly what #82's multimodal convert_messages / _canonical_user_content already handle. The companion client change is in chat-app (OpenGradient/chat-app, branch claude/jolly-hypatia-4BrYt).

What this PR adds

A single regression test (TestImageEditRequestHashContract) that pins, byte-exact, the canonical request-hash serialization for an image-edit request (user turn = edit instruction + prior image as an inline image_url data URI).

The chat-app reproduces this same canonical form client-side to verify the TEE signature (it mirrors _convert_content_part / _canonical_user_content). If the gateway's attachment-digesting serialization ever changes, the client's signature verification silently breaks — this test guards that cross-repo contract, and asserts the raw image bytes are digested away (never inlined) in the signed payload.

Note on the base branch

#82's branch was stale (cut from an old main, missing the image-generation/image_output models the studio uses, and in merge conflict). I rebased it onto current main and force-pushed so it's clean and testable; this PR stacks on the rebased branch. Verified locally: full suite (64 tests) green; the canonical form matches the chat-app client byte-for-byte (409 bytes).

🤖 Generated with Claude Code


Generated by Claude Code

The chat-app sends an "edit the last image" request as a user turn with
the edit instruction plus the prior generation inline as an `image_url`
data URI, and reproduces the gateway's canonical request form client-side
to verify the TEE signature. Pin that canonical serialization byte-exact
so a change to attachment digesting can't silently break the client's
signature verification.
@adambalogh adambalogh closed this Jun 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants