Claude Fable 5's Relentless Proactivity: A Debugging Session

On June 11, 2026, Simon Willison witnessed Claude Fable 5 (part of Claude Code) autonomously debug a CSS bug in Datasette Agent using a chain of unexpected tricks. Given a single screenshot and the prompt "Look at dependencies to help figure out why there is a horizontal scrollbar here", Fable executed a multi-step investigation spanning browser automation, custom server code, and template injection.

The Bug

A horizontal scrollbar appeared in the jump menu chat prompt of Datasette Agent. Willison suspected the cause lay in a dependency (likely Datasette itself). He started a fresh Claude session in his datasette-agent checkout, dragged in the screenshot, and issued the one-line prompt.

Fable's Toolkit

Fable began by figuring out how to run the local development server, including fake environment variables. It then launched a Playwright Chrome session and toggled visible scrollbars via defaults write com.google.chrome.for.testing AppleShowScrollBars Always. After cycling through Firefox and WebKit in Playwright without reproducing the bug, it identified Safari as the default browser.

Fable then built a test HTML page at /tmp/textarea-scrollbar-test.html and opened it in real Firefox. When osascript was blocked by macOS permissions, it pivoted to a Python workaround using uv run --with pyobjc-framework-Quartz to enumerate windows and take screenshots via screencapture -x -o -l /tmp/safari-cases.png.

Triggering the Bug

To open the modal dialog (triggered by the / key), Fable edited Datasette's templates to inject JavaScript that simulated a keyboard event:

This caused the modal to open 1.2 seconds after page load.

Custom CORS Server

To extract measurements from the running application, Fable wrote a minimal Python HTTP server using only the standard library:

from http.server import HTTPServer, BaseHTTPRequestHandler
class H(BaseHTTPRequestHandler):
    def do_POST(self):
        n = int(self.headers.get("Content-Length", 0))
        open("/tmp/diag.json", "w").write(self.rfile.read(n).decode())
        self.send_response(200)
        self.send_header("Access-Control-Allow-Origin", "*")
        self.end_headers()
    def do_OPTIONS(self):
        self.send_response(200)
        self.send_header("Access-Control-Allow-Origin", "*")
        self.send_header("Access-Control-Allow-Headers", "*")
        self.end_headers()
    def log_message(self, *a): pass
HTTPServer(("127.0.0.1", 9999), H).serve_forever()

It then injected JavaScript into the running app to POST diagnostic data:

const host = document.querySelector("navigation-search");
const ta   = host.shadowRoot.querySelector("textarea");
const cs   = getComputedStyle(ta);
fetch("http://127.0.0.1:9999/diag", {
  method: "POST",
  body: JSON.stringify({
    dpr: window.devicePixelRatio,
    scrollWidth: ta.scrollWidth, clientWidth: ta.clientWidth,
    whiteSpace: cs.whiteSpace, width: cs.width,
  }),
});

This data was written to /tmp/diag.json and read by Fable.

The Fix

After gathering measurements, Fable hit an invisible guardrail and downgraded to Opus. Opus continued with the same tricks, found the issue (a two-line CSS fix), and verified it. Willison prompted Opus to write a report at /tmp/automation-report.md documenting all techniques.

Cost

The session consumed 68,606 output tokens with a peak context of 113,178 tokens, costing ~$12.11 at full API prices (Claude Fable 5 + Claude Opus 4-8). Willison was on the $100/month Claude Max plan with a limited Fable allowance.

Security Implications

Willison emphasizes the double-edged nature of Fable's proactivity. While impressive for debugging, the same capabilities could be exploited by prompt injection attacks. "Running coding agents outside of a sandbox has always been a bad idea," he warns, citing Johann Rehberger's "Normalization of Deviance in AI" concept. Fable's ability to write arbitrary code, control browsers, and exfiltrate data makes sandboxing critical.

What You Should Do

If you use Claude Code or similar agents, run them in sandboxed environments (containers, VMs) with restricted network and filesystem access. Consider using tools like firejail or Docker. Monitor agent behavior with logging and auditing tools like AgentsView. And always review the code an agent generates before merging.