Browser gate
Before an account's browser loads anything, it goes through one gate: a headed launch, the account's proxy with its exit in the account's country, the account's one device, the locale of its home country, and a self-check in the page and a worker. The gate is python/browser/proxyGate.py, with the run's device and home prepared by prepareRun. Rules 11, 12, 15, 16, 17 and 92, with rule 84 for platforms that run without a proxy.
Headed launch
REQ-GATE-01: A Camoufox launch is never headless
Every Camoufox launch is headed, with humanize on and the cursor shown. A launch that asks for headless is refused with unguardedLaunch, and there is no flag that turns the headed window off. Rule 11.
Checked by: code and SubQ
REQ-GATE-02: The caller can only pass the options the gate allows
A Camoufox launch takes only headless, humanize, geoip and proxy from its caller. Any other launch option is refused with unguardedLaunch, so a caller cannot change what the gate built.
Checked by: code and SubQ
REQ-GATE-03: A launch that did not go through the gate is refused
Playwright's launch, persistent context and new context are guarded. A launch the gate did not build, or whose options differ from what it built, or that is not headed, is refused with unguardedLaunch.
Checked by: code and SubQ
Proxy
REQ-GATE-04: No browser opens without the account's proxy
A browser opens only when the run has a proxy file. Without one the gate refuses with noProxy, for every launch and for an attached browser alike. Rule 12.
Checked by: code and SubQ
REQ-GATE-05: A Facebook account never runs direct
A proxy file that says the account runs direct is accepted only for a platform other than Facebook. For a Facebook account it is refused with noProxy. Rules 12 and 84.
Checked by: code and SubQ
REQ-GATE-06: The exit IP must be in the account's country
The gate finds the proxy's exit IP and its country. When that country is not the account's, the gate refuses with proxyCountryMismatch. Rule 12.
Checked by: code and SubQ
REQ-GATE-07: An exit with no known timezone is refused
When the exit IP has no known timezone, the gate refuses with proxyCountryMismatch, because the browser's timezone is set from it.
Checked by: code and SubQ
REQ-GATE-08: A proxy too slow to reach Facebook is refused
The gate times Facebook files through the proxy. When the best time is over the limit (LOG_PROXY_MAX_MS, 2500 ms by default), it refuses with proxyTooSlow. Rule 33.
Checked by: code and SubQ
Device
REQ-GATE-09: The first launch makes the account's one device
When the run has no stored device, the gate makes one Windows device (screen, fingerprint config, preferences and a geolocation pinned near the home city, or near the exit when the city has no coordinates) and marks it created so it is saved to Twenty once. Rule 15.
Checked by: code and SubQ
REQ-GATE-10: Every later launch replays the stored device
When the account has a stored device, every launch is built from it, and only the per-launch values (timezone, WebRTC IP, locale, humanize, cursor) are set fresh. A new device is never made over a stored one. Rule 15.
Checked by: code and SubQ
REQ-GATE-11: An unreadable stored device is refused
A stored device that cannot be read, is not a version-1 Windows profile, has no pinned geolocation or stores per-launch keys is refused with deviceProfileInvalid, and no browser opens. Rule 15.
Checked by: code and SubQ
Home locale
REQ-GATE-12: The locale comes from the home country's table
The account's locale and Facebook locale come from HOME_COUNTRIES by its home country. A country not in the table is refused with noHomeLocale. Rule 16.
Checked by: code and SubQ
REQ-GATE-13: The pinned locale reaches the launch
The run's languages are the locale and its base language. The launch sets the browser's locale, its language list and its requested locale from them, so navigator, Accept-Language and Intl agree. Rule 16.
Checked by: code and SubQ
Self-check
REQ-GATE-14: The timezone must be the exit IP's, in page and worker
Before any page loads, the gate reads the timezone in a page and in a worker. When either is not the exit IP's timezone (the same offsets all year count as the same), or the page and the worker disagree, it refuses with browserTimezoneMismatch. Rule 17.
Checked by: code and SubQ
REQ-GATE-15: The language and Intl locale must be exactly the pinned locale
In the page and the worker, navigator.language, the Intl locale and the number locale must each be exactly the pinned locale, or the gate refuses with browserLocaleMismatch. Rules 17 and 92.
Checked by: code and SubQ
REQ-GATE-16: The language list must start with the pinned languages
navigator.languages must start with the pinned languages, in order, in the page and the worker. Languages the browser adds after them are allowed. Anything else is refused with browserLocaleMismatch. Rule 92.
Checked by: code and SubQ
REQ-GATE-17: The browser's exit IP is the one the gate checked, or in its country and timezone
The self-check reads the browser's own exit IP. When no IP echo answers, it refuses with selfCheckFailed. When the IP differs from the one the gate checked, it is refused with browserExitIpMismatch, except on an attached browser, where a residential proxy can change its IP between the gate's check and the browser opening: there a new exit is located and accepted only when it is in the account's country and on the same timezone. Rules 17 and 118.
Checked by: code and SubQ
REQ-GATE-18: A failed self-check stops the browser before Facebook loads
When the self-check refuses, the browser is closed (Camoufox) or the error is raised before anything else loads (an attached browser, which its driver then stops). Rule 17.
Checked by: code and SubQ