Skip to content

feat(computer): [settings] defaults for computer apps, and chromium on WebsiteBrowserEnvironment - #453

Merged
earakely-scale merged 5 commits into
mainfrom
edgararakelyan/fd-4938-m59-chromium-on-websitebrowserenvironment
Nov 3, 2026
Merged

earakely-scale merged 5 commits into
mainfrom
edgararakelyan/fd-4938-m59-chromium-on-websitebrowserenvironment

Conversation

@earakely-scale

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

Copy link
Copy Markdown
Collaborator

What and why

This lands two issues in one PR, as agreed in the design note (eight decisions, signed off Nov 2):

chromium is the first app that needs [settings], and M1.10's "done when" is shown through it.

[settings] for computer apps

An app's settings now come from four layers, each overriding the one before by top-level field. A table or list is replaced whole.

  1. The class's Settings defaults.
  2. The app env's [settings] in its env.toml.
  3. The computer env's settings beside the app in its apps entry: apps = [{ env = "chromium", settings = { locale = "fr-FR" } }].
  4. The deploy's env_params.app_settings.<app>.
  • At put, layers 2 and 3 are checked against the app's Settings: an unknown name, a build setting, a secret's value or a wrong type is refused. A required setting may be left to the deploy.
  • At deploy, the merged values are checked as a whole (params.app_settings) and handed to the app in AGENTENV_APP_SETTINGS as before.
  • The deploy record gains computer.app_settings: exactly what each app is handed, all four layers merged, with secrets withheld. The app's class fills in the rest. env_params is still recorded as given.
  • Gate 3 probes each build with the apps' defaults, as a deploy with no env_params boots it, so a required setting that an env supplies doesn't fail the probe.
  • Storage: the app env's document gains settings, and a computer env's app refs gain settings. Both are left out when empty, so existing documents don't change.

chromium on WebsiteBrowserEnvironment

  • chromium.py is now a subclass: the build, an unpack step and Chrome for Testing's policy folder. Chrome launches directly (chromium/chrome/chrome --no-sandbox --class=Chromium), so the wrapper script and its own --user-data-dir are gone.
  • The base class gains three things:
    • --disk-cache-dir, under ~/.cache. It's an owned flag, and the folder is emptied before each launch, so no episode inherits another's cache.
    • --disable-dev-shm-usage, also owned, added only when /dev/shm holds under 1 GiB. Docker gives 64 MiB, so today it stays on wherever the computer runs in Docker. Sizing /dev/shm from an app's declared need is FD-5052 (M8.50), before M8.10.
    • geolocation and notifications on BrowserSettings, each deny (the default) or ask. They're written into the profile's Default/Preferences before each launch, not into a managed policy file, which the session user could otherwise rewrite.
  • chromium's own policy list folds into the base's. The base already held all of it except the two prompt policies, which are now settings.
  • start_urls defaults to the base's ["about:blank"] instead of [].
  • The shipped env.toml spells out its defaults under [settings], so authors see how an app's settings are set.
  • dialogs moves to M5.10, which answers dialogs. The issue text is updated.

Not in this PR: the control connection (M5.10), browser/v1's operations (M5.11), the data plane (M5.13), chromium alone (M8.10), and an app env that names another app env (left to M8.10 or M8.24).

Overlap: William's draft #448 adds fields beside app_settings in utils/params.py and to the deploy record in env_computer_provider.py. Whichever lands second rebases.

How it was tested

  • ruff check: clean.
  • Unit and protocol tests: 2623 passed (tst/unit/env/envs, tst/unit/bundle, packages/agentenv-protocol/tests). New ones cover:
    • put refusing bad defaults, in the app env and in an apps entry;
    • the four layers merging in order, the deploy record's app_settings withholding secrets, and env_params recorded as given;
    • a required setting that an env gives satisfying a deploy;
    • storage round trips, with documents unchanged when there's nothing to store;
    • [settings] and apps-entry settings read from bundle folders, and refused when malformed;
    • the base's cache flag, the /dev/shm threshold at 64 MiB and at 1 GiB, and both new flags refused in a subclass's command;
    • Preferences written before each launch for deny and ask, merged with what's there, with the cache emptied;
    • chromium's declaration as a website browser, and its unpack step.
  • Integration, in a computer (slow tier), on two agent-environments-admin VMs, amd64 (c6i.2xlarge) and arm64 (c7g.2xlarge). All 9 tests passed on each:
    • chromium_app_test.py (4):
      • gate 3 makes the arch ready with chromium;
      • start tabs open unprompted, and a reset clears the profile;
      • Chrome runs itself with --no-sandbox --class=Chromium, then the base's profile, cache and pipe flags, --lang and, on Docker's 64 MiB /dev/shm, --disable-dev-shm-usage. No socket listens in its session.
      • A loopback page reads its permissions as denied prompt for geolocation = deny and notifications = ask, and the deploy record's app_settings shows both.
      • The desktop-fr computer env lists chromium with locale = "fr-FR" and deploys with --lang=fr-FR. A deploy's time_zone overrides the env's, and the record shows fr-FR with the deploy's zone while env_params stays as given.
    • website_browser_test.py (2): feat(computer): WebsiteBrowserEnvironment, the base class for website browsers #449's tests, its fixture now without its own --disable-dev-shm-usage. The first run caught an argv position check I'd missed; the fix is the second commit, and the rerun passed on both arches.
    • computer_app_test.py (3): every existing computer app still deploys and runs on its settings.
  • E2E in plain containers, on the amd64 VM: 14 of 14 checks passed with the shipped chromium on Xvfb, at Docker's 64 MiB and at --shm-size=1g:
    • the flag is on at 64 MiB and off at 1 GiB;
    • at both sizes the page loads, the pipe answers, and no port listens;
    • the profile's Preferences hold both prompts denied;
    • when the app server is killed and started again, the new browser answers over its new pipe, and the cache Chrome had written (~/.cache/chromium/Default) was emptied before the relaunch.
  • Greptile (round 1) found two issues, both fixed in the fourth commit: the probe booted without the apps' defaults, and the record mixed in only some schema defaults.
  • CI:
    • On the first head, everything was green, CodeBuild included, except the slow-tier shard with the argv check.
    • On the second head, CodeBuild hit a flaky sandbox teardown unit test that this PR doesn't touch (local_sandbox_test.py::test_teardown_kills_a_process_that_ignores_sigterm), and passed on retry.
    • Also on the second head, M1.6's tab test pressed Control+Tab once, and chromium stayed on its first tab. That test passed on both VMs and on the first head. It now presses again while the window still shows the first tab (the third commit), which is safe with two tabs.
  • Rerun on the final head (c32190f1), on fresh amd64 and arm64 VMs after the Greptile fixes: all 9 integration tests passed on each, with gate 3 now probing chromium with its env's [settings], and the 14 plain-container checks passed again. CI is 24/24.
  • Launcher fix (86da990b): a launch while a website browser runs, from its menu launcher say, opens another window over its pipe instead of a second copy. A second copy had emptied the running browser's cache, replaced the server's pipe and recorded a short-lived pid, which left nothing to reset. A protocol test covers it with a fake browser, and chromium_app_test.py now runs the real menu-launcher command in a computer. It checks for two windows, the same browser pid, the cache kept and the app still ready. All 9 integration tests passed on fresh amd64 and arm64 VMs, and CI is 24/24.
  • Every VM, its security group, its key pair and the CodeArtifact token are gone after each run.

🤖 Generated with Claude Code

…n WebsiteBrowserEnvironment

A computer app's env.toml takes [settings], defaults for its Settings, and a computer env can set its own beside an app
in its apps entry; a deploy's env_params override them by top-level field, and the deploy records the merged values.
The shipped chromium becomes a WebsiteBrowserEnvironment: Chrome launched directly on its debugging pipe, with the
base's flags and policies, a cache emptied before each launch, prompt answers in its profile, and its shared memory in
files only where /dev/shm is under 1 GiB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
earakely-scale and others added 2 commits November 2, 2026 14:28
…g and without its own dev-shm flag

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s first tab

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale marked this pull request as ready for review November 2, 2026 23:16
@earakely-scale
earakely-scale requested a review from a team as a code owner November 2, 2026 23:16
earakely-scale and others added 2 commits November 2, 2026 15:23
…keeps what each app is handed

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… window over its pipe

A second copy launched on the same profile handed its window to the first and exited. Before it did, its launch had
emptied the running browser's cache, replaced the server's pipe and recorded the short-lived pid, which left the
server no CDP connection and nothing to stop on reset. An app can now say what a launch does while it runs; a website
browser opens a window over its pipe, and every other app still starts another copy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@earakely-scale
earakely-scale merged commit 5769cec into main Nov 3, 2026
26 checks passed
@earakely-scale
earakely-scale deleted the edgararakelyan/fd-4938-m59-chromium-on-websitebrowserenvironment branch November 3, 2026 01:27
earakely-scale added a commit that referenced this pull request Nov 3, 2026
…isk form

_probe keeps the disk form's `form` and boots with the apps' defaults as #453 made it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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