A customer wants $47.99 back. The agent finds the order, navigates to the refund page, locates the button.
Before the click fires, the browser automation framework runs its checks. Playwright's actionability system verifies four conditions: the element is visible, stable across two consecutive animation frames, not blocked by an overlay that would intercept the pointer, and enabled. The locator must also resolve to exactly one element. If everything passes, the click executes. If anything fails, the framework waits and retries until timeout.
These checks were built for testing, for verifying that expected UI states exist. They answer one question: can this element receive a click right now? The refund's legitimacy, the approval chain, whether the $47.99 will land in the right account — all outside their scope.
The click fires. What travels through the wire?
In MCP's protocol, a tool invocation is a JSON-RPC request containing a method, the tool's name, and its arguments. That's the complete schema. No standard field for who requested the refund. No field for why. No approval timestamp, no field for which return policy applies. If a tool called process_refund takes an order ID and an amount, those two values are what the protocol carries. The customer's complaint, the manager's approval, the reason code: all of it lives outside the call. If it lives anywhere at all.
The call reaches the server. Was it allowed to?
MCP's authorization layer adds something real. It uses OAuth 2.1 with resource indicators to bind access tokens to a specific server, preventing tokens issued for one service from being replayed against another. This closes a meaningful class of vulnerability. It establishes connection authorization: this client may talk to this server. Should this client process this specific refund, right now, for this amount, under this policy, given this customer's dispute history? The protocol has no way to ask. The refund goes through because nothing in the path had the vocabulary to object.
The $47.99 reverses.
Who knows it happened? The browser confirmed the button was clickable. The tool call carried two values. The transport layer verified the connection was authenticated. No layer in this stack produced a durable record binding the action to an authorization decision, a policy basis, and a verified outcome. MCP's spec recommends that clients log tool usage and prompt users before sensitive operations. Recommendations are not records.
This Friday, a lot of operations teams will be running skeleton crews for the long weekend. Automated workflows will keep processing. Somewhere in those workflows, an agent will issue a refund that nobody authorized, and the system will have no structured way to say so afterward. Worth asking before you leave: at which layer does your stack stop being able to explain what it did?
-
Visa's agent payment guardrails: AP reported that Visa embedded its payment network inside ChatGPT with spending limits, approval steps, and merchant restrictions, showing what authorization infrastructure looks like when disputes are a given.
-
Behavioral fingerprinting of agents: A May 2026 study found that browser fingerprints alone struggle to distinguish agents from each other, but behavioral signals like typing and scrolling patterns separate agents from humans and from one another, complicating the recognition problem for sites deciding which automation to trust.
-
OWASP's agentic security framing: The 2026 OWASP Top 10 for Agentic Applications is a peer-reviewed framework specifically addressing autonomous systems that plan, act, and make decisions across workflows, giving security teams a structured way to think about the gaps this piece describes.
-
Enterprise benchmarks and hidden workflows: A recent research effort called World of Workflows argues that cascading side effects and hidden constraints in enterprise systems can produce "dynamics blindness," where agents advance workflows without detecting that downstream constraints broke.

