// Alloy's Firefox configuration. // // Firefox is Alloy's browser, ruled 2026-08-18 (wiki `alloy-byo-principle`). // A default has to earn it under rule 3 of `alloy-packaging-policy`, and stock // Firefox does not: it arrives with defaults that serve someone other than the // person running it. This file is what pays for the pick, and it is the whole // of what Alloy does to a browser. There is no policy file, no autoconfig, no // profiles.ini, and no userChrome.css. Those were deleted on 2026-07-30 and // they are not coming back. // // THESE ARE DEFAULTS, NOT LOCKS. `pref` rather than `lockPref` is deliberate: // every line here is a starting position the user can change in Settings, and // a locked pref would be Alloy hiding a control while claiming to object to // hidden controls. See wiki `irreducible-complexity-principle`. // // WHAT MAY GO IN HERE, in order. Wiki `alloy-byo-principle`, "Exposing a // hidden control beats setting a value": // // 1. Restore a control the vendor hid. Sets no value, so Alloy's opinion // never enters. // 2. Remove an anti-feature. The test is who the default serves: if the // answer is anyone but the user, it goes. // 3. Set a value to Alloy's preference. Forbidden here. Nothing on this // rung has ever been in this file and the Containerfile asserts it. // 4. Take off a confirm-style gate the vendor put in front of a capability. // It comes off when the act behind it is reversible and the user // navigated there deliberately. It stays when the act is irreversible or // changes the machine's security posture. The test is what the click // costs if the user was wrong, not how expert the user is. // // Rung 4 removes one gate in this file and keeps three, which is what makes // it a rule rather than a licence. The three that stay, named so the next // survey does not re-file them: // // - Installing an unsigned extension. Changes the security posture. // - Setting or clearing the primary password. Security posture. // - Clearing history. Irreversible. // // So this file contains no appearance, no layout, no density and no tab // behaviour. If a diff to it argues about how Firefox should look, the diff // is wrong rather than the rule. // // Pref names and their shipped defaults were read out of Firefox 153.0's // omni.ja on 2026-08-18 rather than remembered. Re-measure when Fedora moves // a major version: Mozilla renames these, and a pref that no longer exists // fails silently, which is the failure mode this file can least afford. // --------------------------------------------------------------------- // Rung 1: controls Mozilla built, supports, and hid. // --------------------------------------------------------------------- // Ships false, which hides the density control in Customize. True puts the // control back and says nothing about which density is right. Compact is one // visible click away and Alloy does not click it: `browser.uidensity` is rung // 3 and stays out of this file. pref("browser.compactmode.show", true); // --------------------------------------------------------------------- // Rung 4: a gate in front of a reversible act the user asked for. // --------------------------------------------------------------------- // Ships true (Firefox 153.0, defaults/preferences/firefox.js:1140), so // about:config puts an "accept the risk" screen in front of a page the user // typed the address of. Every value behind it is a pref the same user can set // back, and nothing there changes what the machine will run. Off by the rung-4 // test. The gates on unsigned extensions, the primary password and clearing // history are the same shape and stay, for the reasons in the header. pref("browser.aboutConfig.showWarning", false); // --------------------------------------------------------------------- // Rung 2: the AI block. // --------------------------------------------------------------------- // Every pref below ships ON, downloads models, and was never opted into: // browser.ml.linkPreview.optin and browser.tabs.groups.smart.optin are both // false in the shipped defaults, which is the tell. Off by the who-does-this- // serve test, and a user who wants any of it turns it back on in Settings. // // The master switch is set AND the feature switches are set. That is not // redundancy: it is the guard against a release that re-gates a feature onto // its own pref, which would silently re-enable it here. // The master switch: the ML runtime and every model download behind it. pref("browser.ml.enable", false); // The chatbot sidebar, its context-menu entry, and the two badges that exist // to advertise it. pref("browser.ml.chat.enabled", false); pref("browser.ml.chat.page", false); pref("browser.ml.chat.menu", false); pref("browser.ml.chat.page.menuBadge", false); pref("browser.ml.chat.page.footerBadge", false); // Link previews, including the long-press gesture that triggers them. pref("browser.ml.linkPreview.enabled", false); pref("browser.ml.linkPreview.longPress", false); // Model-driven tab grouping. Both halves: `enabled` is the feature and // `userEnabled` is the surface that offers it. pref("browser.tabs.groups.smart.enabled", false); pref("browser.tabs.groups.smart.userEnabled", false); // --------------------------------------------------------------------- // Rung 2: telemetry. // --------------------------------------------------------------------- // Serves the vendor. The two datareporting prefs are the real handles, since // they gate submission itself rather than collection. pref("datareporting.healthreport.uploadEnabled", false); pref("datareporting.policy.dataSubmissionEnabled", false); pref("toolkit.telemetry.unified", false); // Studies ship experiments to a machine that did not ask for one. pref("app.shield.optoutstudies.enabled", false); // Add-on recommendations built from a profile of what the user browses. pref("browser.discovery.enabled", false); // --------------------------------------------------------------------- // Rung 2: advertising. // --------------------------------------------------------------------- // Serves advertisers. Sponsored placements on the new tab page and in the // address bar. `system.showSponsored` is the feed itself rather than the // checkbox, so it goes too, and the unifiedAds pair is the newer delivery // path for the same thing. pref("browser.newtabpage.activity-stream.showSponsored", false); pref("browser.newtabpage.activity-stream.showSponsoredTopSites", false); pref("browser.newtabpage.activity-stream.system.showSponsored", false); pref("browser.newtabpage.activity-stream.unifiedAds.spocs.enabled", false); pref("browser.newtabpage.activity-stream.unifiedAds.tiles.enabled", false); // Sponsored address-bar suggestions. pref("browser.urlbar.suggest.amp", false); pref("browser.urlbar.suggest.quicksuggest.sponsored", false); // --------------------------------------------------------------------- // Rung 2: tracking protection. // --------------------------------------------------------------------- // Ships at "standard", which serves the ad industry rather than the user. // Strict is the category Firefox already offers; this picks the one that // protects, not a setting Mozilla does not support. pref("browser.contentblocking.category", "strict"); // --------------------------------------------------------------------- // NOT HERE, and each for a reason // --------------------------------------------------------------------- // Pocket. Gone from Firefox: Mozilla shut the service down and 153 carries no // `extensions.pocket` pref at all. It was on Alloy's list from the 2026-07-30 // estate and would have been a dead line. // // browser.uidensity. Rung 3. `browser.compactmode.show` above already puts // the user one control away, which is the cheaper move and the honest one. // // userChrome.css, the fifty-preference estate, the enterprise policy. Deleted // 2026-07-30 and out of scope by guard 1.