Skip to content

feat(computer): a website browser running alone is a computer, on the ubuntu-24.04-headless base with the page driver - #471

Merged
earakely-scale merged 4 commits into
mainfrom
edgararakelyan/browser-computer
Nov 4, 2026
Merged

earakely-scale merged 4 commits into
mainfrom
edgararakelyan/browser-computer

Conversation

@earakely-scale

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

Copy link
Copy Markdown
Collaborator

What and why

A website browser running alone is now a computer. This is the first of three PRs for the browser as a computer, part of FD-5116. Its decisions are in the design note, and the evaluation compared it with a separate front door.

chromium deployed alone now runs on a new base, ubuntu-24.04-headless, which has no display, with a new page driver, whose screen is chromium's active tab. It deploys through the computer provider like any computer, and gate 3 probes it the same way.

The browser computer

  • ubuntu-24.04-headless is Ubuntu 24.04 with no display server or desktop (display = "none"). supervisord runs every program as the session user, including a stand-in site proxy on 127.0.0.1:3128. The stand-in forwards everything and refuses nothing; the shared site proxy replaces it later.
  • The page driver serves the seven computer_* tools and the pointer and keyboard groups over browser/v1's new page/viewport, page/capture and page/input, on chromium's own socket.
    • A screenshot is the page.
    • Input reaches the page as CDP input events.
    • A tab that paints nothing within 3 s (1 s with no URL yet) shows white, as a desktop browser shows it.
  • chromium's env.toml names ubuntu-24.04-headless and page, so Env.get("chromium").deploy() is the browser computer. A desktop with chromium is a computer env that lists it, as the chromium test bundle's desktop already is.

Decisions 4–8 of the note

  • A crash fails the computer for good (decision 4).
    • ReadyCheck gains final.
    • While a final check fails, computer-ready/v1's status carries failed, saying why.
    • boot.ready() raises ComputerFailed at once rather than waiting out its timeout.
    • The page driver marks its browser check final once the launch log has an exit. Its tools then answer with the same detail.
  • Headless comes from the display (decision 5). A website browser runs alone, and headless, exactly when its computer's display is none. AGENTENV_BROWSER_ALONE and AGENTENV_BROWSER_OPEN_WEB are removed: nothing set them but the old prototype, and the open web will need a display of its own.
  • The page operations are framework-only browser/v1 operations (decision 6), like every extension operation.
  • One website browser per page computer (decision 7). A driver's computer/v1 card now says screen: "desktop" | "page", from its class's screen_kind; drivers already name methods screen. AppDeclaration gains browser: true for a WebsiteBrowserEnvironment. put refuses a computer env, or an app deployed alone, whose driver's screen is a page unless it has exactly one website browser.
  • Unpainted tabs and captures (decision 8): white for a tab that paints nothing, and captures through Page.captureScreenshot with optimizeForSpeed.

Also fixed in the control connection: a page attached as it opens is held to the window's size before it runs, headless. And the page driver releases a modifier with its own bit off, as a real keyboard does.

Not in this PR:

  • the navigation, tab, dialog and upload tools (PR 2);
  • the HTML Fixture Desk for gate 3's input checks (PR 3);
  • the real site proxy;
  • /dev/shm sizing;
  • WebSocket forwarding on /svc/<app>/.

Publishing: releases now publish ubuntu-24.04-headless as they do ubuntu-24.04: ghcr.io/scaleapi/agentenv-ubuntu-24.04-headless, its base digest bumped by Dependabot. A base with no disk form gets no disk image. Until a package admin makes the new package public, a run builds the base from its folder instead of pulling it.

Compatibility: AppDeclaration forbids unknown fields. A hub on an older protocol can't load a website browser env put by this version until its pin is bumped. Other apps' stored declarations don't change, because browser is left out unless it's true.

How it was tested

  • ruff check: clean.

  • Protocol tests: 1001 passed. The new ones cover:

    • a final check failing, and the status's failed;
    • the screen feature and its check;
    • browser: true on a website browser's declaration and on no other app's;
    • the active tab's capture, including a tab that paints nothing (3 s, or 1 s with no URL);
    • page input, which takes only input calls and sends them in order;
    • the viewport hold before a page runs;
    • capture and input with no tab open.
  • Unit tests: 11,729 passed. test_a_token_signs_the_clone was left out, because it waits on git credential fill on this laptop, on main too. The new ones cover:

    • the page driver: its keys, clicks, typed text, white capture, final check, and calls once the browser has ended;
    • put refusing a page computer with no browser or two, and an app alone that isn't one;
    • boot.ready() raising ComputerFailed at once.
  • Integration, slow tier, on agent-environments-admin VMs (amd64 c6i.2xlarge, arm64 c7g.2xlarge):

    • browser_computer_test, on chromium deployed alone:
      • gate 3 makes the arch ready, and its probe passes 28 checks with none failed;
      • its tools click, double-click, type, replace a field with Control+A, press Enter and scroll on a page, and the screenshots show it;
      • chromium runs with --headless=new at its window's size, nothing runs X, and nothing listens but the driver and the stand-in proxy;
      • killed with SIGKILL, the app server and then the driver come back, and the computer is ready again;
      • chromium killed with SIGKILL fails the computer for good. The status's failed names the signal, and a screenshot answers with the same detail.
    • chromium_app_test, website_browser_test and computer_app_test, on the desktop: all pass, the popup test included.
    • Each passes on both arches, last at 72530bed, after the rename and Greptile's fixes: 12 of 12 on each.
  • Greptile, round 1 (2/5): four findings, all fixed in e6c92732:

    • the page driver ignored held keys: Shift held now types a as A, which gate 3's P6 expects, and a held modifier carries to clicks, drags and scrolls;
    • headless, a new page wasn't held until it was sized: each now waits, and is told to run even if preparing it fails;
    • a failed browser could take input again once its server relaunched it: every page call is now refused with why;
    • the stand-in proxy kept IPv6 brackets in CONNECT.

    The new unit and protocol tests cover each. Greptile then gave 5/5.

  • CI on 72530bed: 25 of 25, CodeBuild included.

  • Not run: gate 3's input checks on a page (P3–P7, P9) stay unverified until PR 3's HTML Fixture Desk. The run with a real site proxy waits on it.

🤖 Generated with Claude Code

RetriggerView in GreptileConfidence Score: 5/5

The changes appear safe to merge; no new blocking issue was found.

Summary

Adds standalone Chromium computers on ubuntu-24.04-headless, with the page driver supplying screenshots and input.

  • The page driver turns a browser’s active tab into a computer screen.
  • Page-screen computers require exactly one website browser.
  • A no-display Ubuntu base gives browser-only computers a home.
  • A browser exit now fails page-computer startup with its reason.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  A["Standalone chromium"] --> B["ubuntu-24.04-headless"]
  B --> C["page driver"]
  C -->|"browser/v1 page operations"| D["Chromium app server"]
  D -->|"CDP"| E["Active tab"]
  C -->|"Recorded browser exit"| F["Computer permanently failed"]
Loading

Reviews (3) · Last reviewed commit: "refactor(computer): name the headless ba..." · Reviewed by Greptile

… browser-24.04 base with the page driver

chromium deployed alone now runs on browser-24.04, a base with no display, with the page driver, whose screen is its
active tab, over browser/v1's new page/viewport, page/capture and page/input. A ready check can be final: while one
fails, computer-ready/v1 says the computer failed and why, and boot.ready() raises at once. A website browser runs
headless exactly when its computer has no display. A driver's card says its screen, and put refuses a page computer
unless it has exactly one website browser, which its AppDeclaration now says it is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale requested a review from a team as a code owner November 4, 2026 00:20
earakely-scale and others added 3 commits November 3, 2026 16:27
…hes ubuntu-24.04's, its digest bumped by Dependabot

A base with no disk form gets no disk image. The shipped driver aliases now include page.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…licks, a failed browser stays failed, and headless pages wait for their size

Shift held types a as A, and a held modifier carries to clicks, drags and scrolls. Once the browser has ended on its own,
every page call is refused with why, even after its server launches another. Headless, each new page is held until it is
sized to the window, then told to run, and told to run even if preparing it fails. The stand-in proxy takes IPv6
literals in CONNECT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ide ubuntu-24.04, for what sets it apart

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale earakely-scale changed the title feat(computer): a website browser running alone is a computer, on the browser-24.04 base with the page driver feat(computer): a website browser running alone is a computer, on the ubuntu-24.04-headless base with the page driver Nov 4, 2026
@earakely-scale
earakely-scale merged commit 0b361a2 into main Nov 4, 2026
27 of 28 checks passed
@earakely-scale
earakely-scale deleted the edgararakelyan/browser-computer branch November 4, 2026 01:14
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