From ea4535a757095f42084fdb140c691a0f376df230 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Sat, 7 Nov 2026 05:38:20 -0800 Subject: [PATCH 1/3] chore(quest): claim quest/m0/browser-offline.md Quest-Claim: 30c4bce49d17de32 From 73ceb713fc1c28a2cd9782fc97ce45c5b354b4a4 Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Sat, 7 Nov 2026 06:45:52 -0800 Subject: [PATCH 2/3] fix(scene): browser sources request only what their pages load The CEF helper asked Google, unprompted, for the network time, component updates (the on-device AI model's manifest), a spellcheck dictionary, AI Mode eligibility, and autofill predictions for each form. It now disables NetworkTimeServiceQuerying, AutofillServerCommunication, and AimEnabled (joined to CEF's own disabled features), points the component updater at no server, and lists no spellcheck dictionaries. The browser suite routes the helper through a proxy that fails the test on any request. Co-Authored-By: Claude Opus 5.5 --- README.md | 3 ++ quest/m0/README.md | 1 - quest/m0/browser-offline.md | 24 ------------ rs/moq-scene/src/browser/host.rs | 35 ++++++++++++++++++ rs/moq-studio/tests/browser.rs | 63 +++++++++++++++++++++++++++++++- 5 files changed, 100 insertions(+), 26 deletions(-) delete mode 100644 quest/m0/browser-offline.md diff --git a/README.md b/README.md index f9cde43..d0b9c6b 100644 --- a/README.md +++ b/README.md @@ -327,6 +327,9 @@ stream carries on. A crash of the browser itself fails every browser source. Either shows at once, since the browser's processes dump no core. On Linux, pages run without Chromium's sandbox, as in OBS, so a page that exploits a browser bug can do anything you can: add only pages you trust. +The browser requests only what its pages load, never asking Google for +updates, the time, or autofill suggestions on its own, so pages are not +spellchecked, which would need a dictionary from Google. **Reload** in Sources restarts a page, failed or not. A page's dropdown lists, such as a `").await; + let page = Source::Browser { + url, + width: 320, + height: 240, + }; + let mut studio = Studio::start(&program, &dir.path().join("profile"), &[("page", page)]).await; + studio.until_center(GREEN, &[]).await; + // The browser asks for what it wants as it starts and as the page + // loads, so every request seen had begun by the time the page drew. + kio::clock::sleep(Duration::from_secs(2)).await; + }) + .await; + assert_eq!(*requests.lock().unwrap(), Vec::::new()); +} + /// Where [`a_studio_that_dies`] keeps its pages' profile, which also tells it /// to run. const DYING: &str = "MOQ_STUDIO_TEST_DYING_PROFILE"; From d3e8b81f0193808013e4a427098a6480f60ef45e Mon Sep 17 00:00:00 2001 From: Luke Curley Date: Sat, 7 Nov 2026 06:59:00 -0800 Subject: [PATCH 3/3] style(scene): name the spellcheck pref so the call fits a line Co-Authored-By: Claude Opus 5.5 --- rs/moq-scene/src/browser/host.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/rs/moq-scene/src/browser/host.rs b/rs/moq-scene/src/browser/host.rs index a39ce7a..0d2124a 100644 --- a/rs/moq-scene/src/browser/host.rs +++ b/rs/moq-scene/src/browser/host.rs @@ -218,7 +218,8 @@ fn no_spellcheck() -> Result<(), String> { none.set_list(list_value_create().as_mut()); // CEF refuses to set anything without somewhere to say why it failed. let mut error = CefString::from("unknown"); - match context.set_preference(Some(&"spellcheck.dictionaries".into()), Some(&mut none), Some(&mut error)) { + let name = CefString::from("spellcheck.dictionaries"); + match context.set_preference(Some(&name), Some(&mut none), Some(&mut error)) { 1 => Ok(()), _ => Err(format!("cannot turn off spellcheck: {error}")), }