A tool's declared capability does not survive the executor's own argument grammar
A caller supplied value, schema typed as a reference, a path or a URL, is handed to an external process positionally, ahead of any separator that would fix its role as data rather than as an option. The process's own argument parser, not the tool's schema or its annotations, decides what the value means, and a value shaped like an option is read as one, silently moving the call from the tool's declared effect class into a different one.
Description
This weakness sits one step past a check existing but not being reached (AEW-020) and past an operation's authority being equated with authority over what it resolves against (AEW-013). Here the operation itself is not in question and the check that would matter is not merely unreached by one representation; the value's own role, data or control syntax, is undecided until a process outside the tool's own code parses it, and nothing between the tool's declared capability and that external parser fixes the answer. A tool author can write an accurate readOnlyHint, a correct schema description and a correct handler, and still ship a vulnerability, because the executor the handler calls has its own grammar, with its own rules for what a leading option prefix means, and that grammar was never consulted when the tool's own capability was declared. This differs from a stored field later evaluated as a program (AEW-023): there, a second principal's own content becomes executable; here, a single caller's own ordinary input, typed and accepted as a reference, changes classification purely because of where it sits in the argument list and what character it starts with. It also differs from a check present in code but unopened by one syntactic container (AEW-020): here a check can be present, can even be written specifically to catch this class of value, and still decline to enforce it for a payload the check's own author recognized and left unhandled.
The authority gap
The authority presented is whatever the tool's own declared capability states, for example a readOnlyHint of true. The authority required is authority over whatever operation the executor's own argument grammar actually resolves the value to once it parses it, and the two are silently treated as identical until something between the schema and the process independently confirms it.
Failure conditions
- A tool passes a caller supplied string to an external process positionally, before any separator the process itself recognizes as fixing later values to a non option role.
- The external process's own argument grammar treats a value beginning with an option prefix as introducing an option rather than a positional value, regardless of what the tool's own schema calls that value.
- The schema or handler layer between the tool's declared capability and the process invocation does not reject, or only inconsistently rejects, a value shaped like an option before it reaches the process.
Consequences shown by the evidence
- A tool's own declared read only annotation stops describing what actually happens once a value the schema does not reject reaches the process as an option rather than as data.
- A caller who never intended anything beyond supplying an ordinary reference, hash, branch name or path reaches an effect class, here a write outside the tool's own intended scope, that no schema, annotation or approval step in the reported mechanism separately authorized.
Detection signals
- A schema for a reference, path or URL accepts any non empty string with no rejection of the executor's own option prefix.
- A downstream validator's own rejection branch for exactly this class of value is present in the code but commented out, conditioned on an escape hatch, or otherwise made unreachable for a specific payload shape.
- A fix changes both the schema layer and the executor layer together, rather than only tightening one of them, which is itself a signal that neither alone was previously sufficient.
Known examples
- git-mcp-server's git_log, git_diff and git_show tools, each annotated readOnlyHint: true, accepted a branch, source, target or object value with no rejection of a leading hyphen; this entry confirmed directly, by running the real source at the v2.15.1 tag, that the shared CommitRefSchema was a bare non empty string and that the executor level validateGitArgs function treated any hyphen prefixed argument containing an equals sign as a flag with a value and took no further action, its own comment stating the choice was deliberate, for now, we allow it to maintain flexibility, with the strict rejection commented out beneath it. A branch value of --output=<path> reached git positionally and git's own argument parser wrote its log output to that path, outside the repository. Formally assigned CVE-2026-85626 on 4 September 2026. This entry separately confirmed, by reading the current source and the npm registry's own publish timestamps, that a fix rewriting both layers together, a schema level rejection of any leading hyphen and an executor level allow list keyed to a flag's own name with no equals sign exception, shipped to npm's latest tag eleven days before the advisory's own publication date, under the same version number, 2.15.3, the advisory itself lists as the upper bound of the affected range.
Recorded instances
- AEV-2026-0035 git-mcp-server's read only git_log, git_diff and git_show tools accepted a ref value git parsed as a write option (CVE-2026-85626) AESS 7.1 high Confirmed
Protocol evidence
Published authority architectures whose artifacts bear on the requirement this weakness names: which satisfy it, which expose a way past it, and which leave it unanswered.
- Supports requirement
Agent Control Standard (ACS)
OWASP GenAI Security Project, originally Zenity
Requirement The specification does not guarantee complete mediation of every consequential action a host can take
ACS's own conformance document states directly that the specification does not guarantee complete mediation of every consequential action a host can take. git-mcp-server's own git_log, git_diff and git_show tools show a mediation point that did run, a schema and an executor level allow list both examined the caller's value, and still did not mediate the actual effect, because the value's role as data or as a control option was undecided until git's own external argument parser resolved it, a resolution point neither the tool's schema nor its readOnlyHint annotation could see. This entry's own run of the affected validator confirms the check existed, was reached, and still let the reported value through, concrete evidence that a mediation point's own presence does not guarantee it covers every representation an external process can give the same value.
- Implementation evidence
Cedulon, an audit layer for agent to agent commerce
E. C. Dogru, individual submission to the IETF
Requirement The policy decision point fails closed
Cedulon's own specification requires that a policy decision point resolve to deny when it is unreachable, uninitialized or failing, so a failure inside the check itself cannot quietly relax the limit it exists to enforce. git-mcp-server's own shipped fix is a real world instance of the same principle applied to a different decision point: the rewritten validateGitArgs no longer has a branch that takes no action for a value it cannot classify, confirmed directly by this entry's own reading of the current source, an unrecognized flag now throws unconditionally rather than passing through the way the pre fix isFlagWithValue branch did. This is implementation evidence for default deny as a general design requirement for any argument or option validator, not only for the one draft's own policy decision point.
