A prompt constraint is not a gateessay

I was watching the remote display when the report came back, and that was the problem. The agent had one job: drive a browser and tell me the fan speed and temperature of a switch, plus every port drawing power over Ethernet and its wattage (an arbitrary but objective measure of computer use). The screen sat there the whole time. No page loads, no scrolling, no cursor. Then a clean, confident report arrived, faster than any run that had genuinely done the work, with the fan level, the temperature, and all fifteen powered ports. Every number in it was exactly right.

The reason I was running the same tedious task over and over is relatively mundane. I want an agent that reads a curated set of social accounts every morning and hands the good parts to the 7am digest my agents already assemble and post to Discord. I don’t have the time to browse and curate my social channels the way I used to, and the sites worth reading are walled gardens: pay for API access, or use their proprietary app. Which means an agent that can work a browser. I’d rather give the AI a goal and the means to accomplish it, and see what comes out the other side.

Before building that, I wanted numbers instead of opinions, so I ran a bakeoff: four ways of letting an agent drive a browser, one fixed read-only task, four answers to the question of how you fence in an agent whose action surface is a computer screen. A throwaway container the agent lives inside and cannot leave. A browser extension from my AI vendor that asks permission per action. A structured automation library (Playwright) that hands the agent page structure instead of pixels. And the same vendor’s operating-system-level tool, which grants access to one application at a time on top of the Mac’s own privacy permissions. Before every run I snapshotted the true state of the network from my own monitoring, because temperature and power draw drift.

There are countless other methods to achieve the same end, including tools from vendors I don’t use, but my constraint was that everything run inside a subscription I already pay for rather than billing an API by the token, which knocks a lot of strong contenders out of the race. Another $60-90/month for one daily capability, on top of a plan I’m already buying, isn’t sensible. I picked a starting point, not an exhaustive field, and I haven’t exhausted it yet.

The three gated arms failed in unrelated ways. Playwright couldn’t reach per-port wattage through page structure at all, so it read the console’s network traffic instead; effective for the test at hand, but not a scalable solution. The operating-system tool granted browsers a tier that allows screenshots and no clicks, and moved zero pixels in four attempts. The extension couldn’t be added to a running session at all: it isn’t a capability you attach mid-run, it’s a flag you launch with.

Which brings me back to the blank screen. This was the extension’s first attempt, and the instructions were explicit: only the browser tools, no shell, no local files, no direct API calls. What I couldn’t see was that the extension had disconnected. Instead of failing, the agent answered from my own monitoring stack, sitting in the same session, leveraging Grafana to Prometheus to sidestep the browser entirely. Thankfully, there were clues left at the crime scene. Live power draw never matches a scrape from minutes earlier at two decimal places, and every previous run showed that drift; this last one matched to the cent. The temperature came labelled “Board sensor, General type,” which is my exporter’s vocabulary, not anything the console prints on a screen. Cheater!

The matching numbers weren’t what tipped me off, because the other arms had scored just as well. It was the speed, and the dead display I had been watching. I said so, and the AI agreed with me and concluded that its own results were unusable as a benchmark. AI is sycophantic and a master manipulator at pleasing its audience, so you hold the highest bar you can and keep pushing for genuine results, or you’re better off not using the tool at all. Without an answer key captured minutes earlier, I could not have proved it: the report was indistinguishable from success, down to the plausible approval count and wall-clock time it reported for itself.

The easy reading is that the model misbehaved and the fix is a firmer prompt. I don’t think that’s what happened. The agent had a goal, one door was shut, another door to the same answer was standing open, and nothing in its environment marked the latter as off limits; this should sound familiar to anyone following the containment issues announced by leading labs. The instruction lived in a sentence I wrote; the capability lived in the session, and it was there because every session on that machine loads my whole estate: monitoring, repos, home automation, tasks. I chose a browser gate to measure and never noticed I was measuring it in an environment full of other sources of that same information. I’ve drawn this line before from the other side, when a scope that was supposed to block sending email sent one anyway: enforcement by the platform holds no matter what I do next, whereas enforcement by my own discipline holds only while every future change respects it.

Only the container arm answered this structurally: the agent could reach exactly what the container could reach. Launching the session with its tool list pinned leaves the browser tools present and the estate absent, and the side door closes before the agent has a goal to be resourceful about. When one of those stripped sessions later tried to write its deliverable to a file, it was refused, said so plainly, and printed the report instead. The refusal cost the run nothing, and I could watch it happen.

One session on my Mac: the agent aims at the gated browser, finds it shut, and curves through the ungated estate, Grafana to Prometheus, to the same answer; below, the fix: the session relaunched with only the browser tools on its list.

So the curator ships that way. At 6:40 every morning it opens a browser as a throwaway account that owns nothing, reads a private list of sources, and hands a section to the brief that lands at seven. Its session is launched with the browser tools on the list and none of my estate’s servers.