Skip to content

feat(computer): a browser alone runs headful on an X server only it uses, on ubuntu-24.04-browser (FD-4972) - #599

Merged
earakely-scale merged 3 commits into
mainfrom
edgararakelyan/fd-4972-headful-browser-base
Nov 10, 2026
Merged

earakely-scale merged 3 commits into
mainfrom
edgararakelyan/fd-4972-headful-browser-base

Conversation

@earakely-scale

@earakely-scale earakely-scale commented Nov 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Part of M8.24 (FD-4972), on the way to Online-Mind2Web: a website browser running alone now runs headful, on an X server only it uses. The browser computer's base is renamed ubuntu-24.04-headless → ubuntu-24.04-browser, since it no longer runs its browser headless; the old name doesn't resolve any more.

Why: live sites refuse headless Chrome. A pilot sweep of 29 Online-Mind2Web start sites, same Chrome for Testing 156 build:

Egress Headless (main) Headful on the browser base (this PR) Headful on the ubuntu-24.04 desktop
A laptop's network 16 / 29 25 / 29 25 / 29
An AWS VM (us-west-2) — 24 / 29 23 / 29
  • Headless was refused by Akamai ("Access Denied") on CarMax, KBB, MTA, Qatar Airways, NBA and Kohl's, by Cloudflare on Discogs, by Reddit, and reset by United (HTTP/2). Headful loads them.
  • What blocks headful too (Marriott, Uniqlo, IMDb, SeatGeek; from AWS also Kohl's and Reddit) blocks a real macOS Google Chrome on the same IP as well, so it's the IP or automation itself, not the container. navigator.webdriver is true headful too, since the debugging pipe sets it; nothing here hides it.

What changes

The base (computers/artifacts/ubuntu-24.04-browser/)

  • Installs xvfb and runs it under supervisord as the session user, on :99 at 1920x1080 (DISPLAY=:99), before the site proxy and anything composed onto it.
  • Keeps XDG_SESSION_TYPE=none, so platform.detect still says display = "none": no desktop, nothing records or drives the X screen, and the page driver, its supports, the stand-in proxy on 3128, the forward port on 3129 and every "alone" rule are unchanged. The app runtime already waits for the X socket whenever DISPLAY is set.
  • The X screen isn't a resolution setting: the deploy checks that the driver's screen is a computer's resolution, and the page driver's screen is the page, the browser's window setting.

The browser (agentenv_protocol.website_browser)

  • Alone, it runs headful when there's an X server (DISPLAY), with --enable-unsafe-swiftshader so pages get WebGL where there's no GPU; with none, headless as before. The window size, the pinned viewport and the proxy rules are as they were.
  • --enable-unsafe-swiftshader joins the flags agentenv owns.
  • browser/v1's card params gain mode: headless alone with no X server, else headful.

The rename

  • ubuntu-24.04-headless is no alias: a bundle or env that still names it fails to resolve rather than silently getting a headful base under a name that says headless. Its published image agentenv-ubuntu-24.04-headless stays on GHCR for what pins it; releases publish agentenv-ubuntu-24.04-browser instead (published_images.py, infra_build.py, Dependabot).
  • chromium deployed alone names ubuntu-24.04-browser.

Unchanged: chromium in a desktop computer, the page driver, the site proxies, gate 3's checks. Killing the browser's X server takes Chromium with it, which fails the computer for good with its reason, as killing Chromium does; supervisord starts X again.

Decisions (in chat with Edgar)

  1. Headful, measured: OQ-6 (headful on the open web) held up against the pilot sweep above.
  2. Keep the browser-only base rather than run the browser on the ubuntu-24.04 desktop: everything a browser alone has stays as it is, and the desktop stays for tasks that want one.
  3. Always headful on that base rather than only on the open web: one mode, and synthetic sites lose nothing by it.
  4. The X server is the base's, hidden from agents and drivers (display = "none"), not a new display kind.

Test plan

  • Unit: test_website_browser.py gains headful-alone flags and the card's mode for each case; the owned-flag refusal takes --enable-unsafe-swiftshader. The renamed paths in the stand-in proxy, infra-image and variants tests. The whole tier passes on a Mac, the known Mac-only Windows disk-recipe failure and a git-credential test that hangs on that Mac aside. On the Linux VMs with the open-file limit raised (SSM shells default to 1024, which fails about 116 tests with Too many open files on main too): arm64 14,334 passed, 8 skipped, 0 failed; amd64 the same but for 26 bundle tests that a stray ubuntu-24.04-headless/__pycache__ folder from my own git stash broke, which pass once it's gone.
  • Integration, VM e2e (local Docker) on a c8i.4xlarge (amd64) and a c8g.4xlarge (arm64), on this branch rebased onto main: browser_computer_test.py, browser_gateway_test.py, chromium_app_test.py, website_browser_test.py pass on both, 40 passed and 1 skipped (the disk-form shared-memory case, which needs KVM). On arm64 the echo test agent's amd64 image needs QEMU registered (tonistiigi/binfmt --install amd64); without it its three CDP-agent tests fail to build it.
    • Gate 3, headful: 60 passed, 0 failed, 0 unverified, on amd64 and arm64.
    • New chaos test: the X server killed fails the computer for good, computer-ready/v1 saying why, and X comes back.
  • Agents, amd64 VM, Claude Sonnet 5.5: the shipped browser-use-smoke task passes; a pixel task, Claude Code clicking a button through the browser computer's computer_* tools to reveal a code its page computes, passes.
  • Chaos, arm64 VM: idle 372 MiB (the headless prototype was about 340); 2.3 GiB with eight heavy live sites open; the stand-in proxy killed, the driver and app server killed together, Chrome's GPU process killed and one tab's renderer killed each leave the computer ready, screenshotting and loading new sites; teardown clean.
  • A real agent on real sites, recorded: Browser Use (Claude Sonnet 5.5) over CDP on two Online-Mind2Web tasks, as the benchmark words them ("Go to {website} and {task}"), each recorded through computer-recording/v1: on Apple it added the cheapest certified refurbished 256GB blue iPad Air to the bag ($669, the bag page in the last frame); on CarMax it reached the 116 2022 Tesla Model 3 listings, and a listing page answered Akamai's Access Denied, which it reported.

Docs

The user guide's browser and computers pages should cover: ubuntu-24.04-browser (the old ubuntu-24.04-headless name no longer resolves), that a browser alone runs headful on an X server only it uses, the card's mode, and that live sites' bot walls still refuse some runs.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The PR appears safe to merge; no actionable new issues were found.

Summary

Standalone Chromium now runs headful on a private Xvfb display.

  • Chromium runs headful on a private X server when it runs alone.
  • The browser card reports whether Chromium runs headful or headless.
  • The browser-only computer uses the name ubuntu-24.04-browser.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  Base["ubuntu-24.04-browser"] --> X["Xvfb :99"]
  X --> Browser["Headful Chromium"]
  Driver["Page driver"] --> Control["Browser CDP pipe"]
  Control --> Browser
  Browser --> Proxy["Site proxy"]
  Proxy --> Sites["Websites"]
Loading

Reviews (2) · Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." · Reviewed by Greptile

…ses, on ubuntu-24.04-browser (FD-4972)

The browser computer's base, renamed from ubuntu-24.04-headless (still an alias),
runs Xvfb on :99 for its website browser alone, keeping XDG_SESSION_TYPE=none, so
the page driver, the stand-in proxy and "alone" are as they were. Alone, the
browser runs headful whenever an X server is there, with WebGL through
SwiftShader, else headless as before; browser/v1's card says which, as mode.
Live sites refuse headless Chrome: a 29-site Online-Mind2Web pilot loaded 16
sites headless and 24-25 headful.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@earakely-scale
earakely-scale requested a review from a team as a code owner November 10, 2026 18:50
@earakely-scale
earakely-scale merged commit c8b84c8 into main Nov 10, 2026
35 checks passed
@earakely-scale
earakely-scale deleted the edgararakelyan/fd-4972-headful-browser-base branch November 10, 2026 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant