Chrome for Testing and Google Chrome are built from the same source, but they do not have the same fingerprint, and that difference decides what each one can prove. Chrome for Testing is Google's unbranded build: the right control for "is this caused by our patches?" and the wrong one for "does this look like Chrome?". We spent four days on a detector signal before running the first question, and the answer took ninety seconds.

Four days on the wrong assumption

IPHey scored every Mosaic profile Unreliable, 90 out of 100, with one signal on its browser card: an inconsistent browser fingerprint. A branded Google Chrome on the same Mac scored Trustworthy. So we assumed something in our patch series caused it, and went looking.

The search was thorough. We compared the JavaScript surface, then property descriptors, then enumeration order. We captured the TLS ClientHello with a raw listener and compared it field by field. We compared the HTTP/2 SETTINGS frame and header order. We tried claiming the real stable build number instead of ours. Every layer came back identical to branded Chrome, and the verdict did not move.

What would have ended it on day one was Google's own unpatched Chrome for Testing 153.0.8010.36, pointed at the same page. It earns the identical verdict. None of our patches are in it, so none of them can be the cause. One run rules out the whole series, and it should have been the first run rather than the last.

The fingerprint is changed inside the engine, not painted on topIn Mosaic: Its own Chromium. Tesseract Chrome: values changed in C++, not JavaScript. Free holds 3 profiles. Pro is $49 a month for any number.

How it works: Its own Chromium

What Chrome for Testing answers, and what it cannot

A control answers one question, and it is worth writing down which before trusting it.

Chrome for Testing shares the source and the branding flag with our engine and has none of our changes. So it isolates the patches. If it gets the verdict too, the cause is either in stock unbranded Chromium or in the environment, and bisecting our series would have been days of rebuilds searching for something no patch was responsible for.

It cannot answer whether a browser looks like Chrome, for two reasons we measured.

First, it contradicts itself. Its brand list read Chromium/153, Not_A Brand/8 while its User-Agent read Chrome/153.0.0.0. A browser whose client hints disagree with its own User-Agent raises an inconsistency signal on its own account. So "the untouched Google build fails too" was true and circular at the same time, and we used that argument twice before noticing.

Second, its version and its branding were tangled. An earlier control had been taken while the machine's Google Chrome was still on 152, so the only 153 to compare against was unbranded. Version and branding were one column, and the wrong one got the credit: we wrote that the detector had not learned the new major yet. When Chrome updated to 153, two binaries of the same major got opposite verdicts, and the real variable showed itself.

What a branded control found

With the right control in place, branded Chrome on the same machine and page, the difference was one call. speechSynthesis.getVoices() returns 199 voices on branded Chrome and 180 on any unbranded build of the same version. The missing 19 are Google's network voices, Google US English, Google Deutsch and the rest, supplied by a component that ships only when Chromium is compiled as Chrome.

Our comparison script had read the voice list, got 0 from both browsers because it read before the list loaded, and carried an exemption saying the field races the probe. Patch 0145-branded-tts-voices now restores the 19 voices in our engine, where the component's own would arrive.

The same rule, at smaller scale

The rule held on a much smaller question too. A check reported our engine's AudioContext.outputLatency as 0 against a claimed 0.0053, which looked like a broken patch. Branded Chrome 154, same page, same click, also answered 0 until real audio had played, and 0.024 after 1.2 seconds of it. The engine was reproducing Chrome exactly; the check was reading before the value existed. One launch of the control settled it in minutes.

So our order of questions is now fixed. First, does unpatched Chromium of the same major do it? That rules our patches in or out. Then, does the Google Chrome people run do it? That says whether the result is about looking like Chrome at all. A single third-party verdict is not evidence either way, so both get several rounds.

The first difference that branded control found, twenty APIs switched on by a test config, is written up in twenty APIs Chrome doesn't have. The same kind of control showed a detector flagging an untouched Chrome in Pixelscan calls stock Chrome masked, and the case for owning the engine at all is in why we built our own Chromium.