Skip to content

Add browser location bridge and lease convergence - #399

Open
tnsardesai wants to merge 11 commits into
mainfrom
hypeship/browser-location-bridge
Open

tnsardesai wants to merge 11 commits into
mainfrom
hypeship/browser-location-bridge

Conversation

@tnsardesai

@tnsardesai tnsardesai commented Sep 18, 2026 •

Copy link
Copy Markdown
Contributor

summary

  • accept generation-ordered location bundles for the active lease epoch; lease resets are authorized by the instance JWT or the metro-verified control-plane marker (the former Authorize browser location lease resets #400, included here)
  • send Chromium a monotonic browser generation per accepted bundle (persisted, independent of lease epochs) and mark a bundle applied only after Chromium reports timezone, renderer/worker and network-context acknowledgements for that generation
  • GET /browser/location confirms applied live against the running Chromium, so a restarted or unreachable browser is never reported applied
  • the launcher initializes /etc/localtime from the persisted accepted bundle, else KERNEL_BROWSER_TIMEZONE, else TZ, and execs Chromium without TZ so Chromium's Linux watcher follows runtime changes; a restarted Chromium starts in the session's current timezone
  • explicit locales and timezones are validated against lib/browserlocation/capabilities.json (Chromium/154.0.8037.97+tzdata-2026c+a1a4f3e6807fb867, 412 locales, 598 timezones), generated by TestBrowserLocationCapabilities: a locale is listed when Intl.DateTimeFormat and Intl.NumberFormat resolve exactly that tag and Intl.Collator resolves it or a parent; a timezone when the image ships it and Intl accepts it. The status reports capabilities_version
  • internal location CDP commands stay blocked on customer CDP
  • a failure to persist an accepted bundle returns 500 with configure step browser_location, which is part of the ChromiumConfigureError.step enum; lib/oapi/oapi.go is regenerated with make oapi-generate, which also adds the multipart browser_location field

dependency

Provisioning needs no API change: when KERNEL_BROWSER_TIMEZONE is absent the launcher uses TZ (the variable production already sets), so kernel #4204 was closed as superseded.

Runtime application requires the kernel-browser #92 artifact at 368c6172de4d4b4c5e9aae74e32fc8f61f456f81.

Based on kernel/kernel-images@e970762ff809eff9da680b1c3792e85ab60bef15 (current main).

tests

  • go test ./cmd/... ./lib/oapi/..., including a test that every configure step is a valid ChromiumConfigureError.step and that a persistence failure returns a valid browser_location step
  • make build; go test, go test -race, go vet on ./cmd/api/api ./cmd/chromium-launcher ./lib/browserlocation ./lib/cdpclient ./lib/devtoolsproxy ./lib/metrics
  • locally built headless image with the fix computer controls hang #92 build (run 37918236863, before fix computer controls hang #92's off-the-record language change) and the API/launcher before the configure-step enum change:
    • TestBrowserLocationCapabilities (check mode): manifest matches the artifact exactly
    • TestBrowserLocationRuntimeUpdate (3/3): Chromium runs without TZ; lease reset LA→Singapore, configure →Berlin, same-value retry, stale generation 409, no restart (PID and start time unchanged), Chromium restart returns to the accepted bundle, new lease epoch →New York. At each applied, the page, its already-running worker and date (without TZ) report the new timezone and locale without polling
    • TestBrowserTimezoneFollowsLocaltime (production TZ + KERNEL_BROWSER_TIMEZONE environment, raw /etc/localtime replacement): the first replacement after start needs rewrites (~1.8 s); later changes converge in 3–58 ms
  • the same timezone test passes on the stock Chrome for Testing image

limitations

  • headful and snapshot restore/wake and pool-reuse runs were not executed locally; TestBrowserLocationRuntimeUpdate needs E2E_KERNEL_BROWSER=1 and a kernel-browser image, so stock CI images skip it
  • the manifest must be regenerated (UPDATE_BROWSER_LOCATION_CAPABILITIES=1) whenever the browser or image tzdata changes, and copied to kernel packages/api/lib/browserlocation/capabilities.json

Note

Medium Risk
New lease-ordered control-plane state, host /etc/localtime mutation, and dependency on kernel-browser CDP; mitigated by validation, auth on reset, and blocking internal CDP on the public proxy.

Overview
Adds runtime control of browser timezone, locale, and languages without restarting Chromium. Callers send generation-ordered bundles tied to a lease epoch; the API persists state, rewrites /etc/localtime, and reconciles via custom CDP (Browser.setKernelBrowserLocation / getKernelBrowserLocation) until Chromium reports timezone, browser, renderer, and network-context convergence.

New surfaces: browser_location on Chromium configure (async accept, 409 on stale/conflict/wrong epoch), GET /browser/location (live-checks applied against running Chromium), and POST /internal/browser-location/reset (instance JWT or trusted control-plane header). Lease resets bump a monotonic browser generation separate from per-epoch bundle generations.

Supporting pieces: embedded lib/browserlocation capability manifest for validation, Prometheus metrics, DevTools proxy blocking of internal location CDP from customer WebSockets, and launcher startup that applies persisted timezone and drops TZ from Chromium’s environment so /etc/localtime updates propagate.

Reviewed by Cursor Bugbot for commit 76e7bfb. Bugbot is set up for automated code reviews on this repo. Configure here.

@tnsardesai
tnsardesai force-pushed the hypeship/browser-location-bridge branch from a7d8253 to 9755de8 Compare October 9, 2026 07:29
@tnsardesai tnsardesai changed the title Add browser location bridge Add browser location bridge and lease convergence Oct 9, 2026
…owser location

Send Chromium a monotonic browser generation per accepted bundle and mark a bundle applied only after Chromium reports renderer, worker, host-timezone and network-context acknowledgements for that generation. A Chromium restart clears applied state until the new process acknowledges. Explicit locales and timezones are validated against a capability manifest generated from the Chromium 154 browser in the image instead of ICU component-locale readback.
TestBrowserTimezoneFollowsLocaltime starts Chromium with the production TZ and KERNEL_BROWSER_TIMEZONE environment, checks Chromium runs without TZ, and replaces /etc/localtime A to B at runtime without a restart. TestBrowserLocationCapabilities regenerates or checks the capability manifest. TestBrowserLocationRuntimeUpdate drives reset, configure, retries, stale generations, Chromium restart and a new lease on a kernel-browser image.
…ed live

The launcher initializes /etc/localtime from the accepted bundle the image API persisted, so a restarted Chromium starts in the session's timezone instead of the VM's startup zone. GET /browser/location reports a bundle applied only after the running Chromium confirms that generation with every component acknowledged, so a restarted or unreachable browser is never reported as applied while the upstream change is still being detected. The runtime e2e posts to /configure, the image's configure route.
@tnsardesai
tnsardesai marked this pull request as ready for review October 9, 2026 22:54

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit b743ced. Configure here.

Comment thread server/cmd/api/api/chromium_configure.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant