Repository navigation
fix(marketing): stop inferring Mac CPU arch from the WebGL renderer - #7054
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Team Run ID: 📒 Files selected for processing (37)
🚧 Files skipped from review as they are similar to previous changes (16)
Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review. 📝 WalkthroughWalkthroughThe ChangesMac architecture-aware downloads
Estimated code review effort: 3 (Moderate) | ~20 minutes Merge Risk: ⚪ Minimal · up to The download flow now uses client hints when available, defaults unconfirmed Macs to Apple Silicon, and provides an Intel fallback link. No current merge-blocking risk remains. Sequence Diagram(s)sequenceDiagram
participant DownloadInterstitial
participant usePlatform
participant detectPlatform
participant navigator.userAgentData
DownloadInterstitial->>usePlatform: request platform information
usePlatform->>detectPlatform: resolve platform
detectPlatform->>navigator.userAgentData: request architecture hint
navigator.userAgentData-->>detectPlatform: architecture value or failure
detectPlatform-->>usePlatform: PlatformInfo with archSource
usePlatform-->>DownloadInterstitial: platform and architecture source
DownloadInterstitial->>DownloadInterstitial: select download and render fallback notice
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 37.50% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 8 functions across 4 files. (17 skipped: 17 unsupported.) Full details: Description checkExplanation The description clearly explains the problem, implementation, design decisions, testing, manual QA, limitations, and follow-ups. It does not reproduce the exact template checklist or confirm the maintainer-edit setting, but the required change and validation details are substantially complete. ✨ Finishing Touches 💡 2📝 Generate docstrings 💡
⚔️ Resolve merge conflicts 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
🧹 Preview Cleanup CompleteThe following preview resources have been cleaned up:
Thank you for your contribution! 🎉 |
There was a problem hiding this comment.
No issues found across 3 files
Architecture diagram
sequenceDiagram
participant Client as Marketing Site (Browser)
participant UA as navigator.userAgentData
participant UA2 as navigator.userAgent
participant Hook as usePlatform (React)
participant Download as Download Logic
participant Analytics as PostHog Event
Note over Client,Analytics: Mac Architecture Detection & Download Flow
Client->>Hook: Mount usePlatform hook
Hook->>Hook: Initialize with Platform.Unknown
Hook->>UA2: Read navigator.userAgent
UA2-->>Hook: User agent string
alt Mobile device detected
Hook->>Hook: Classify as Platform.Mobile
Hook-->>Client: Return Mobile + NotMac source
else Mac detected (mac os x|macintosh)
Hook->>UA: Call getHighEntropyValues(["architecture"])
alt Browser exposes client hint
UA-->>Hook: Return architecture value
Hook->>Hook: normalizeArch() - prefix matching
alt Architecture is x86/x86_64/amd64
Hook->>Hook: Classify as MacIntel + ClientHint source
else Architecture is arm/arm64
Hook->>Hook: Classify as MacAppleSilicon + ClientHint source
else Unrecognized or empty architecture
Hook->>Hook: Default to MacAppleSilicon + Default source
end
else No userAgentData (Safari/Firefox) or error
UA-->>Hook: Browser exposes no architecture
Hook->>Hook: Default to MacAppleSilicon + Default source
end
Hook-->>Client: Return Mac platform info
else Windows/Linux/Other OS
Hook->>Hook: Classify based on UA patterns
Hook-->>Client: Return OS platform + NotMac source
end
Client->>Download: User initiates download
Download->>Download: Determine DMG filename
Download-->>Client: Serve arm64 or x64 build
Client->>Analytics: Track download_started/manual_clicked
Note over Client,Analytics: Includes archSource field<br/>(client-hint vs default vs not-mac)
There was a problem hiding this comment.
All reported issues were addressed across 37 files (changes from recent commits).
Not reviewed (too large): packages/i18n/locales/cs/messages.ts (~2 lines), packages/i18n/locales/de/messages.ts (~2 lines), packages/i18n/locales/en/messages.ts (~2 lines), packages/i18n/locales/es/messages.ts (~2 lines), packages/i18n/locales/fr/messages.ts (~2 lines), packages/i18n/locales/id/messages.ts (~2 lines), packages/i18n/locales/it/messages.ts (~2 lines), packages/i18n/locales/ja/messages.ts (~2 lines), packages/i18n/locales/ko/messages.ts (~2 lines), packages/i18n/locales/nl/messages.ts (~2 lines), and 7 more - if these are generated or fixture files, add them to ignored paths to exclude them from future reviews.
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
0344776 to
f6ffc3d
Compare
|
Note GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer. |
f6ffc3d to
6fa575b
Compare
|
Re the two cubic P2/P3 notes: the fallback direction is now Apple Silicon again (f29b25e), with the data behind that choice in the description's Design Decisions. The test comment and PR body are updated to match what ships. |
detectMacArch read the WebGL unmasked renderer string and treated any string without "apple" in it as proof of an Intel Mac. Apple Silicon visitors whose browser masks or software-renders that string were handed Superset-x64.dmg (#7036). Architecture now comes from UA Client Hints, which report the CPU directly in Chromium and report the hardware even under Rosetta. When the browser exposes nothing (Safari, Firefox) the page defaults to Apple Silicon, labels the pill plain "macOS" instead of claiming a detection, and links the Intel build under the button. PostHog says that is the right default: Safari and Firefox are ~13% of Mac downloads and nearly all of them are Apple Silicon, so guessing x64 would mis-serve far more people than it rescues. download_started and download_manual_clicked carry archSource, and download_arch_switched fires when someone takes the Intel link, so the share of guessed visitors is measurable. Rebuilt on main after #7092 re-keyed the catalogs by English text; the note's 16 translations are written in by hand. Fixes #7036 Claude-Session: https://claude.ai/code/session_01DyrTQocncE9XV6tHTXe3J8
fe3e40b to
1e811b3
Compare
Fixes #7036
Summary
detectMacArchread the WebGL unmasked renderer string and treated any string withoutapplein it as proof of an Intel Mac. Apple Silicon visitors whose browser masks or software-renders that string were handedSuperset-x64.dmg.navigator.userAgentData). When the browser exposes nothing (Safari, Firefox) the page defaults to Apple Silicon, labels the pill plain "macOS" instead of claiming a detection, and links the Intel build one click below the button.download_started/download_manual_clickedcarryarchSource(client-hint/default/not-mac), and a newdownload_arch_switchedevent fires when someone takes the Intel link, so PostHog can size how often the default is wrong.Why / Context
The reporter was on an M5 MacBook Pro and got the Intel build, then had to go to GitHub Releases to fix it by hand.
Inferring a CPU property from a GPU string is wrong regardless of this bug: the two aren't related, and the renderer string is absent under software rendering and forged by fingerprint-resistant browsers and extensions. Every genuine failure path already fell back to Apple Silicon; only a present but wrong renderer string produced Intel.
/downloadis the only surface that can serve the x64 build.apps/webandapps/docshardcode arm64.How It Works
detectMacArchnow:navigator.userAgentData.getHighEntropyValues(["architecture"]), which reports the CPU directly in Chromium and is unaffected by GPU state.normalizeArch), sox86_64andarm64map correctly rather than falling through.archSource: "default"when there is no signal at all.The interstitial treats
archSource: "default"as unconfirmed: the platform pill reads "macOS", and a line under the button says the browser didn't report a chip and linksSuperset-x64.dmgfor Intel Macs. TheReleaseListfrom #7047 still lists every asset below.Design Decisions
Why default unconfirmed to Apple Silicon, not x64. An intermediate commit on this branch defaulted to x64 because it runs on either chip via Rosetta. PostHog for the last 30 days says that mis-serves more people than it rescues:
Safari and Firefox have no client hint, so an x64 default sends all ~626/month to the Intel build, and nearly all of them are Apple Silicon. Three things make that landing worse than "degraded but runs": a fresh Apple Silicon Mac has no Rosetta installed, so first launch is an install prompt; the auto-updater keeps the user on x64 for every future release; and Apple has said Rosetta narrows after macOS 27. An arm64 build on an Intel Mac fails loudly with a "can't be opened" dialog, and the note on the page already points at the fix.
Why not invert the WebGL check to require a positive
intel|amd|radeonmatch: it would fix the reported case but keep a heuristic that misfires on exactly the privacy-configured browsers that cause the problem. Deleting it removes the failure mode instead of narrowing it.Why prefix matching in
normalizeArch: exact=== "x86"would send an engine reportingx86_64to the Apple Silicon default, which is this same silent-wrong-build bug pointed the other way. I can't test a real Intel Mac, so the assumption is made cheap to be wrong about.Why no
Sec-CH-UA-Archserver tier: it covers no browsernavigator.userAgentDatadoesn't, and it makes the HTML vary on a request header while Next silently drops theVarythat would make that safe to cache.Why not a universal binary: it removes the guess entirely, and Cursor, Slack and Obsidian ship universal. But VS Code's universal build is 1.74x its arm64 build, which would put Superset near 1GB, paid by every Apple Silicon user on every download and auto-update. Worth a deliberate decision, not this PR.
Manual QA Checklist
Reproduced and verified on real Apple Silicon (M5 Max), driving Chrome over CDP against the page with downloads denied.
Before the fix, against production
superset.sh/download:Superset-x64.dmgMesa OffScreen) requestedSuperset-x64.dmgSuperset-arm64.dmg(control)After the fix, against this branch:
SwiftShader:
Superset-arm64.dmg, page labels it "macOS · Apple Silicon"Stock Chrome:
Superset-arm64.dmg(control)Client hint
x86:Superset-x64.dmg, page labels it "macOS · Intel"Client hint
x86_64:Superset-x64.dmgClient hint
arm64:Superset-arm64.dmgUnrecognised value (
wasm):Superset-arm64.dmg(safe default)Real browsers against the final commit (
bundrivers over CDP / WebDriver BiDi on throwaway profiles, downloads denied or github.com blocked):armSuperset-arm64.dmg--use-angle=swiftshader(renderer = SwiftShader, the old Intel trigger)armSuperset-arm64.dmgarch -x86_64, chrome://version says "x86_64 translated")armSuperset-arm64.dmgarmSuperset-arm64.dmgSuperset-arm64.dmgSuperset-x64.dmgprivacy.resistFingerprinting(renderer = "Mozilla", the old Intel trigger)Superset-arm64.dmgSafari 26.6: not driven. WebDriver needs
sudo safaridriver --enableon this machine. Safari has nouserAgentData(WebKit standards-positions format 1 #70 is still open), so it takes the same path Firefox exercised above.Also confirmed the healthy path was never broken: a port of the old
detectMacArchresolved correctly in Chrome, Safari 26.6, Firefox 148, Arc and Comet on this machine, which is why this only ever bit a subset of visitors.Testing
bun run --cwd apps/marketing typecheckbun test --cwd apps/marketing(85 pass, 6 files)bunx biome check apps/marketingbun run --cwd packages/i18n check(strict compile 0 missing across 17 locales, stale audit clean)Confirmed the tests can fail: reintroducing the Intel default turns 4 red, and reverting
normalizeArchto exact matching turns 6 red.Known Limitations
app.superset.sh, which hardcodes arm64 and can't produce x64. The bug fixed here is real and proven; whether it's theirs is unconfirmed.archSourcein PostHog will size it.Macintoshuser agent by default since iPadOS 13, so an iPad visitor hitsdetectMacArch, gets the Apple Silicon default, and auto-downloads a DMG instead of seeing the "open this on your desktop" link. Not a regression (the WebGL path did the same via "Apple GPU"), and PostHog can't size it because it files iPads under Mac OS X too. The standard tell isnavigator.platform === "MacIntel" && navigator.maxTouchPoints > 1, which Claude, Cursor, Obsidian and Postman all use. One-line follow-up.Follow-ups
apps/web/src/app/(agents)/agents/page.tsx:73,apps/web/.../settings/billing/page.tsx:63andapps/docs/.../DownloadButton.tsxhardcode arm64 with no escape hatch. Routing them atsuperset.sh/downloadwould keep this logic in one place.process.archplus a Rosetta check, which catches every path including builds grabbed from GitHub.https://claude.ai/code/session_01YU7cRGNVocDp2PwUCKbzU7
https://claude.ai/code/session_01DyrTQocncE9XV6tHTXe3J8