Mockingjay has had a goal lurking behind it since the start, which is that tests should write themselves. The recorder is a workaround for the fact that they can't yet. The Operator we shipped in April was a fun side project, but it left a thing on the table that we kept poking at. If an agent can run a workflow we describe in English, can it explore an app we point it at and come back with enough of a map for the next agent to write tests against ?
That was the work for September and October.
The first instinct was the wrong one. We started writing a bigger Operator. A single agent, a richer prompt, a longer tool list and a JSON object on the side that we updated as the agent went. The agent was now expected to navigate the page, classify the page, decide what to do next and remember everything it had seen well enough not to revisit it. By turn 15 the JSON object was lying about the shape of the app. The agent was lying about what it was looking at, and the loop kept going for another 40 turns because there was no stopping condition the agent couldn't talk itself out of. A linear conversation can't describe an application that doubles back on itself.
A web application is a graph, with pages for nodes and the ways one page leads to another for edges. The memory of an exploration is a partially built map of that graph, with the agent standing on one node and looking at the next few edges available to it. So, we pulled the graph out of the agent's transcript and put it in a real directed graph. Nodes and edges have schemas. A node carries the URL, the page type the model thinks it is looking at (login, dashboard, form, listing, error and a handful more), whether it requires authentication, the count of interactive elements, the count of forms and a discovery timestamp. An edge is typed, one of direct_link, form_submission, button_click, menu_navigation, ajax_call, redirect, workflow_step or conditional_access, and also carries the element that triggered it, a weight and a traversal count. The graph lives in Postgres on the workflow execution row, the same place the Operator's conversation lives.
The next thing that didn't fit in a single agent was the work itself. There are at least 4 problems on the table at any given step: working out what is on the page, picking the next move, performing it cleanly and writing the result into the graph without duplicating a node we have already seen. They are different shapes, and a single prompt asked to do all 4 does each of them worse than a focused prompt that does one. So, the Explorer has 5 agents.
A coordinator runs the loop. It never sees the page, only the other agents' outputs and the graph. Its tools are the other 4 agents plus update_application_graph, complete_exploration and abort_exploration. On every new page the coordinator is required to call the analysis agent first, before anything else. We added that guardrail in the third or fourth week, after the coordinator kept skipping analysis when it thought it already knew what was on the page.
The navigation agent does browser actions (navigate to a URL, click an element, type into an input, wait for an element to appear), a single atomic action per call. The analysis agent takes a screenshot and returns a structured assessment: page type, authentication state, the interactive elements it can see, error messages if any and the navigation structure. The decision agent picks the next move and a strategy for the run, choosing among breadth_first, depth_first, targeted and mixed, and scores candidate targets with a priority b/w 0 and 1. The graph builder is the agent that writes to the graph, with tools to add or update nodes, add or update edges, query the existing graph and validate its integrity. The others can suggest a change, but only the graph builder commits it. That constraint, more than the agent count, is what stopped the graph from drifting.
The whole thing runs on Sonnet 4.5, which shipped on 29th September, and we moved everything to it in the first week of October. Sonnet 4 had been in the Operator path since May, and 4.5 was a free upgrade for the same price, so there was nothing to decide. The agents share the model and the Bedrock provider. The prompts and the tool sets are what make them different.
We did try Claude Opus 4.1 on the coordinator specifically, for a couple of weeks after it shipped in August. Opus was noticeably better at the long-horizon coordination, with fewer wandering runs and fewer redundant analyses. At several times the price, it wasn't worth keeping as the default. Sonnet on the coordinator is a little worse than Opus and much cheaper, and that was the trade we made.
There are 2 objections to all this, and both are fair.
The first is that 5 agents is over-engineering, and that one agent with the right tools could do this. I half agree. The split came out of debugging rather than architecture astronaut work. Each agent is here because the single-prompt version was visibly worse at that piece, and the roles are a compression of weeks of looking at traces. If a future model can hold all 4 jobs at once without dropping any of them, the agents collapse back into one and we won't miss them. We're not married to 5.
The second is that this is a sitemap crawler with model calls bolted on. Mostly fair on a static site, where a crawler would do most of what we're doing. The model earns its keep where the crawler can't: deciding that a <div> with an onclick handler is the same kind of thing as a button somewhere else, that a modal counts as a different node than the page it sits on, that this form is the same form we filled out 2 hops ago even though the URL has a new id in it. The bookkeeping a crawler does on a static site is easy. On a real SPA the bookkeeping is most of the problem.
Where the Explorer still falls over is, irritatingly, the kind of app where the map would have been most useful. A dense, data-heavy enterprise application with hundreds of pages, 50 of them behind permission gates, 10 variants of the same screen depending on which customer profile is loaded and 3 modes of navigation that share none of the same patterns. The decision agent looks at the candidates and the priority scores cluster too closely to choose well. The run wanders. At hour 2 the graph has the shallow surface of the app mapped pretty well and almost none of the depth. Coverage stalls. We watch the trace for a while and then shut the run down.
Tests do not write themselves yet. The map is the prerequisite, and it is partial on the apps where it would have mattered most. Even where the map is good, we haven't built the next agent yet, the one that reads the graph and writes the cases. We will. Whether the shape we have now survives the next model release, or whether the whole thing wants to be one agent again with a graph as its scratchpad, I don't have a confident answer to. For now we point Sonnet 4.5 at it and read the failures.