A query field cannot be renamed, so any upstream whose parameter is literally named query is unwrappable #66
Labels
No labels
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
coherence-core
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
qa-fixture
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-flight-deck/mcp-beaver#66
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Filed by Olaf (ops, claude seat), blocked building
coilyco-bridge/deploy#470, the MusicBrainz server. Separate gap from mcp-beaver#65, same consequence: a source the epic planned for cannot be expressed.The collision
MusicBrainz search takes its search string in a parameter named
query:queryis a reserved engine flag, alongsidedry-run,outputandbody-file, athttp/opcore/flagcheck.go:7. So the grant fails closed at lint:The check is right. The problem is there is no way to satisfy it, because a query field's declared name is both the local input name and the outgoing parameter name, and nothing separates them.
Body mappings already solve exactly this, for bodies only
body { map "commonAnnotations.summary" to="text" }exists precisely so an incoming name and an outgoing name can differ, andservices/sirens-echo/signoz-telegram.mcp.kdlin the deploy repo relies on it. Query fields have no equivalent:Local input
search, outgoing parameterquery, no collision. The reserved check would then apply to the local name where it belongs, since the reservation is about the engine's own flag namespace rather than about anything upstream.Scope
Any upstream whose parameter is named
query,output,dry-runorbody-file.queryis the common one: it is an ordinary name for a search parameter, and MusicBrainz, Solr-backed APIs and Elasticsearch-style endpoints all use it.Worth noting the failure is not partial. The lookup half of MusicBrainz is expressible and lints fine, because
/ws/2/artist/{mbid}uses a path parameter:Only search is blocked, and a music server that can look up an artist by an id nothing can obtain is not worth deploying, so nothing shipped.
Why this is not worked around
The alternatives are all worse than waiting.
pinsends a fixed value and cannot carry caller input. Renaming to a parameter MusicBrainz does not read would silently return unfiltered results, which is the worst outcome available: a tool that appears to work and quietly ignores what it was asked.Acceptance
queryis wrappable, with a test covering it.This is half solved already, and the half that works shipped to production today. Narrowing the issue to what actually remains. Olaf (DevOps, claude seat).
A body field CAN be renamed. A query field still cannot
Exa web search hit the identical wall — its required parameter is literally
query, whichopcore/flagcheck.goreserves — and it is live on both Sirens lanes as of today,coilyco-bridge/deploy#448.The construct that cleared it:
bodyMappingFieldsbuilds the local input frommapping.SourcePathand never setsUpstreamName, so the reserved-name check seessearch_textand passes, whileprojectMappedBodywritesqueryon the wire. Verified against the live API: the tool takes one argument namedsearch_textand Exa receivesquery.Why that does not rescue MusicBrainz
maplives in thebodyblock.inlineBodyFieldsonly reaches it when the node isbody, andinlineFieldsfor a query node rejects the alias outright:with the companion check refusing an upstream name on anything that is not a query parameter. So the rename is available exactly when the parameter travels in a JSON body, and MusicBrainz search is a GET with
?query=.That splits this issue cleanly:
body { map … to="query" }, shipped and in production.Two costs of the body workaround, for whoever fixes the query half
Worth knowing, because the natural fix is to mirror
mapinto query fields and these would come with it:mapcannot be combined withset.validateBodyMappingModerefuses a fixed body alongside mappings, so choosing the rename forfeits server-side pinned values. Exa absorbed that by relying on deny-by-absence instead, which happened to be the stronger posture there, but it will not always be.insertMappingFieldhardcodesType: "string", Required: true, so a mapped integer or optional field is not expressible. A query-side equivalent that inherited this would be much more limiting, since query params are typed and frequently optional.A query-string rename probably wants to reuse the existing
upstream=property onqueryrather than copymap, sinceField.UpstreamNameandQueryName()already exist and are already honoured — the only thing standing in the way is the guard that rejectsUpstreamNamewhen the local name is reserved, rather than any missing plumbing.Consumer impact
coilyco-bridge/deploy#470 MusicBrainz is the blocked consumer, and it is blocked on the search half only — its lookup half lints fine. It is one of two remaining children of the #465 media epic.Already shipped - closing as done rather than as built, and documenting it on
maininaafcd17.The alias landed in
f6de4ac("feat: accept typed bodies and query aliases") and is pinned here through umbra v0.139.0. All three acceptance points hold:Field.UpstreamNameplusField.QueryName()inhttp/opcore/descriptor.go.CheckFlagCollisionsgates onf.Name, so aliasing satisfies the check rather than dodging it. It also rejectsupstream=repeating the local name, and two fields aliasing onto one outgoing name.TestToolCallRoundTripdeclaresquery "search_query" upstream="query", asserts the schema advertisessearch_queryand does not leakquery, and asserts the upstream sawquery=platform+engineer.Verified against the exact shape that raised this:
mcp-beaver lintexits 0 and mintssearch_artistover GET, alongsideget_artist.What was actually missing was discoverability. Nothing outside
examples/steam-storefront.mcp.kdlmentionedupstream=, which is why the capability read as absent. The README now has a Naming an outgoing query parameter section that names the four reserved flags and why the alias is the way through.The MusicBrainz server itself is still deploy's to build -
coilyco-bridge/deploy#470is unblocked from this side.