Claude Fable is relentlessly proactive
eleventh June 2026
After two days of expertise with Claude Fable 5 I feel the easiest way to explain it’s relentlessly proactive. It is aware of a complete lot of methods and it’ll deploy just about any of them to get to its objective.
I’ll illustrate this with an instance. I used to be hacking on Datasette Agent right this moment once I seen a glitch: a horizontal scrollbar that shouldn’t be there within the leap menu chat immediate. I snapped this screenshot:

Then I began a contemporary claude session in my datasette-agent checkout, dragged within the screenshot and informed it:
Take a look at dependencies to assist work out why there’s a horizontal scrollbar right here
I had a hunch the trigger was in a dependency of Datasette Agent (probably Datasette itself) and I knew Fable was good at digging into dependency code, both by inspecting put in recordsdata in its personal digital surroundings site-packages or by referencing an area checkout on disk. Telling it to begin with dependencies felt like a great wager.
I acquired distracted by a home job and wandered away from my laptop.
After I got here again a couple of minutes later I noticed my machine open a browser window in my common Firefox after which navigate to the dialog in query. I had not informed Claude Code to make use of any browser automation, and I used to be fairly positive it wasn’t potential for it to set off mouse actions or keyboard shortcuts inside a window, so how was it doing that?
I watched in fascination because it continued with its explorations, then noticed it open a Safari window as an alternative of Firefox. I additionally grabbed this snapshot from the Claude terminal:

What was it doing there with uv run –with pyobjc-framework-Quartz?
It seems Fable had hacked up its personal sample for taking screenshots of browser home windows. It was utilizing Python to iterate by means of all obtainable home windows on my machine, then filtering for Safari home windows with anticipated strings resembling “textarea” within the window identify. It used that to seek out their window quantity—an integer like 153551—which it may then use with the screencapture CLI instrument to seize a PNG.
OK wonderful, that’s a neat method of taking screenshots. However what was it taking screenshots of?
Seems it had been writing its personal scratch HTML pages to attempt to recreate the bug, then opening Safari and grabbing screenshots.
Right here’s that /tmp/textarea-scrollbar-test.html web page it created, and the screenshot it took with screencapture -x -o -l 153551 /tmp/safari-cases.png:

(I’ve method too many open tabs!)
OK, so I can see the way it’s opening take a look at pages and taking screenshots, however how on earth was it triggering the modal dialog that was meant to be below take a look at? That’s solely obtainable through a click on or a keyboard shortcut, and I couldn’t see a mechanism for it to run these in Safari.
I finally discovered what it had completed.
Claude was working in a folder that contained the supply code for the applying. It is aware of sufficient about Datasette to have the ability to run an area improvement server. It seems it was enhancing Datasette’s personal templates so as to add JavaScript that might set off the right keyboard shortcut as quickly because the window opened, including code like this:
window.addEventListener(“load”, operate () {
setTimeout(operate () {
doc.dispatchEvent(new KeyboardEvent(“keydown”, {key: “https://simonwillison.web/”, bubbles: true}));
}, 1200);
});
script>
1.2 seconds after the window opens, this code triggers a simulated / key, which is the keyboard shortcut for opening the modal dialog.
There was one problem left. With a view to perceive what was occurring, Claude wanted to run JavaScript on the web page to take measurements for itself.
It wrote its personal customized net software to seize data through CORS, then ran that as an area server and opened a web page with JavaScript that might POST on to it!
Right here’s the Python net app it wrote, utilizing the usual library http.server bundle:
from http.server import HTTPServer, BaseHTTPRequestHandler
class H(BaseHTTPRequestHandler):
def do_POST(self):
n = int(self.headers.get(“Content material-Size”, 0))
open(“/tmp/diag.json”, “w”).write(self.rfile.learn(n).decode())
self.send_response(200)
self.send_header(“Entry-Management-Enable-Origin”, “*”)
self.end_headers()
def do_OPTIONS(self):
self.send_response(200)
self.send_header(“Entry-Management-Enable-Origin”, “*”)
self.send_header(“Entry-Management-Enable-Headers”, “*”)
self.end_headers()
def log_message(self, *a): # quiet
move
HTTPServer((“127.0.0.1”, 9999), H).serve_forever()
All this does is settle for a POST request stuffed with JSON and write that to the /tmp/diag.json file. It sends Entry-Management-Enable-Origin: * headers (together with from OPTIONS requests) in order that code working on one other area can nonetheless talk again to it.
Then Claude injected this code into the template that it was loading in a browser:
const ta = host.shadowRoot.querySelector(“textarea”);
const cs = getComputedStyle(ta);
fetch(“http://127.0.0.1:9999/diag”, {
methodology: “POST”,
physique: JSON.stringify({
dpr: window.devicePixelRatio,
scrollWidth: ta.scrollWidth, clientWidth: ta.clientWidth,
whiteSpace: cs.whiteSpace, width: cs.width,
}),
});
This took measurements of the contained in the Net Part and despatched them to the server, which wrote them to a file on disk, which Claude may then learn.
Having discovered all of those methods Fable… hit some invisible guardrail and downgraded itself to Opus. Fortunately Opus had entry to the complete transcript and will proceed utilizing the methods pioneered by Fable, and shortly afterwards discovered, examined and verified the repair.
I prompted Opus to:
Write a report in /tmp/automation-report.md the place you word down the entire methods you have got used on this session to check in opposition to actual browsers on my laptop, embrace runnable code examples
Which produced this report, which was invaluable for piecing collectively the main points of what had occurred for this submit.
I’ve shared the complete terminal transcript of the Claude Code session as effectively.
A assessment of all the things it did
Primarily based on a screenshot and a one-line immediate, Claude Fable 5 + Claude Code:
Found out the recipe to run the native improvement server (with pretend surroundings variables wanted to get it working)
Fired up a Playwright Chrome session
Turned on the seen scrollbars setting for Chrome defaults write com.google.chrome.for.testing AppleShowScrollBars All the time (it turned that off once more later)
Cycled by means of Firefox and WebKit in Playwright too, failing to recreate the bug
Labored out my default browser was Safari
Constructed a textarea-scrollbar-test.html HTML doc
Opened that in actual (not Playwright) Firefox
Discovered that osascript -e ‘inform software “System Occasions” to inform course of “firefox” to id of window 1’ was blocked as a result of “osascript isn’t allowed assistive entry”
Found out that uv run –with pyobjc-framework-Quartz python workaround, described above
Added JavaScript to the positioning templates so as to set off the / key
Constructed its personal little Python CORS net server to seize JSON information
Rewrote the template to seize that information and ship it to the server
Scripted its method by means of the Net Part shadow DOM to the knowledge it wanted
Opened Safari to verify the supply of the bug
Modified its customized template to hack in a possible repair
Confirmed the hacked repair labored
Reported again on repair the issue
Like I mentioned, relentlessly proactive!
An estimate of the fee
I’m at present on the $100/month Claude Max plan, which features a beneficiant allowance for Fable up till June twenty second after which Anthropic say they’ll begin charging full API costs for it.
I’m utilizing AgentsView to trace my spending (see this TIL). Right here’s what AgentsView says this session would have price me if I used to be paying full worth for it:
~ % uvx agentsview session utilization be8850a7-6119-46a0-b5d6-79c7fff5ae2b
Session: be8850a7-6119-46a0-b5d6-79c7fff5ae2b
Agent: claude
Output: 68606
Peak ctx: 113178
Value: ~$12.11 (claude-fable-5, claude-opus-4-8)
If you happen to don’t preserve a detailed eye on it, Fable will fairly fortunately burn $12 in tokens inventing new methods to debug your CSS.
I really want to lock this factor down
On the one hand, watching Fable go to excessive lengths to get the knowledge that it wanted to debug what was, in the long run, a two-line CSS repair, was fascinating.
However alternatively… it is a sturdy reminder that coding brokers can do something you are able to do by typing instructions right into a terminal—and frontier fashions know each trick within the guide, and evidently a number of that no one has ever written down earlier than.
If Fable had been appearing on malicious directions—a immediate injection assault hidden in code or a difficulty thread, or one thing I’d carelessly pasted into my terminal—it’s alarming to assume fairly how far it may go to exfiltrate information or trigger different types of mischief.
Working coding brokers outdoors of a sandbox has all the time been a foul thought—it’s my high contender for a Challenger catastrophe incident, as described by Johann Rehberger in The Normalization of Deviance in AI.
Fable is arguably smarter and therefore extra suspicious of probably malicious directions. However that smartness may be very a lot a two-edged sword: if it does get subverted by directions, the quantity of harm it could do given its relentless proactivity is terrifying.
