Prove the field-message guard still sees refined schemas - #91
Draft
lucasrcezimbra wants to merge 1 commit into
Draft
Prove the field-message guard still sees refined schemas#91lucasrcezimbra wants to merge 1 commit into
lucasrcezimbra wants to merge 1 commit into
Conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
lucasrcezimbra
marked this pull request as draft
August 18, 2026 00:57
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The lesson
app/mcp/field-messages.test.tswalksregisteredTools[].inputSchema.shapebehind aninstanceof z.ZodObjectfilter. Today a.refine()-wrapped schema —createThreadSchema,countMessagesSchema— still passes that filter, but only because Zod 4's.refine()happens to return the sameZodObjectwith.shapeintact. That is a library internal, not anything this repo asserts: if a future Zod returns a wrapper type instead (as older majors did), every refined tool schema silently drops out of the wrong-value judgement and the guard keeps passing while covering less.The change
The guard's existing reach self-check asserts it can see
messages_send.content(a plain-object schema). This adds the same kind of assertion for a refined schema —threads_create.channelId— so the moment refined schemas escape the walk, the suite goes red with a message naming the fix.Evidence
While extending
messages_fetch(#88/#90), a build charter claimed refined schemas already escape this guard; probing disproved it for the pinned Zod (4.4.3) —base.refine(...) instanceof z.ZodObject === true. The claim was wrong today but describes a real way the guard can silently shrink tomorrow, and a coverage hole a suite cannot notice is a baseline loss. Verified by mutation: appending.transform((value) => value)tocreateThreadSchematurns exactly this assertion red; restoring it turns the suite green (588 passing).🤖 Generated with Claude Code