Skip to content

fix(marketing): route mobile downloads to app stores - #24577

Open
juliusmarminge wants to merge 4 commits into
mainfrom
takeover/pr-18816
Open

juliusmarminge wants to merge 4 commits into
mainfrom
takeover/pr-18816

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Oct 24, 2026 •

Copy link
Copy Markdown
Member

Mobile visitors to the marketing homepage receive desktop installers. Both download buttons now use the existing App Store and Google Play links, including iPad desktop mode; desktop downloads keep their current behavior.

Takeover

Based on @saphid's #18816, rebuilt against current main because homepage logic moved.
Reduced five platform cases to four meaningful regressions and restored the marketing test task so CI executes them. Existing store URLs and desktop release selection are retained.

Evidence

Final-head evidence index · Independent proof audit: SUFFICIENT

Fixture / viewport / preference / DPR Before
c4fa4629eb
After
69b0eb2c4c
Diff0: any RGB delta DiffT: RGB delta >16/255
M01 iphone 390×844 dark / dark, DPR 3; Chromium Safari-UA emulation M01 before M01 after M01 diff0 M01 diffT
M02 iphone 1440×900 dark / dark, DPR 3; Chromium Safari-UA emulation M02 before M02 after M02 diff0 M02 diffT
M03 android 390×844 dark / dark, DPR 3 M03 before M03 after M03 diff0 M03 diffT
M04 android 1440×900 dark / dark, DPR 3 M04 before M04 after M04 diff0 M04 diffT
M05 ipad-desktop 390×844 dark / dark, DPR 2; Chromium Safari-UA emulation M05 before M05 after M05 diff0 M05 diffT
M06 ipad-desktop 1440×900 dark / dark, DPR 2; Chromium Safari-UA emulation M06 before M06 after M06 diff0 M06 diffT
C01 mac 1440×900 dark / dark, DPR 1 C01 before C01 after C01 diff0 C01 diffT
C02 mac 390×844 dark / dark, DPR 1 C02 before C02 after C02 diff0 C02 diffT
C03 windows 1440×900 dark / dark, DPR 1 C03 before C03 after C03 diff0 C03 diffT
C04 linux 1440×900 dark / dark, DPR 1 C04 before C04 after C04 diff0 C04 diffT
U01 unknown 390×844 dark / dark, DPR 1 U01 before U01 after U01 diff0 U01 diffT
U02 unknown 1440×900 dark / dark, DPR 1 U02 before U02 after U02 diff0 U02 diffT
L01 iphone 390×844 light / dark, DPR 3; Chromium Safari-UA emulation L01 before L01 after L01 diff0 L01 diffT
L02 android 1440×900 light / dark, DPR 3 L02 before L02 after L02 diff0 L02 diffT
F01 windows 390×844 dark / dark, DPR 1 F01 before F01 after F01 diff0 F01 diffT
F02 linux 1440×900 dark / dark, DPR 1 F02 before F02 after F02 diff0 F02 diffT

Captured 16/16 matched full-page pairs, 32 diff images, 16 readable before/after section sheets, and 22 collapsed branch transcripts (11 inputs × both SHAs). No required static or B01–B05 case is missing. All 32 final page images passed two byte-identical frames at least 500 ms apart. Every final image and diff was opened for inspection. Headed Chrome for Testing 145.0.7632.6, Playwright 1.58.2 / CDP, Linux x86_64, Xvfb; reduced motion; bundled DM Sans and JetBrains Mono loaded; default font scaling and zoom 100%; no CSS/text autosizing override. All profile DPRs and actual UA/touch/UA-CH/media/viewport values are recorded in the sidecars. Safari UA rows are Chromium emulation, not native Safari/WebKit proof.

Browser DPR stays exactly 3/2/1 from the fixtures. PNG raster output is CSS pixels, CDP scale=1, so a 390-wide page image is 390 pixels wide. The requested 390×844 or 1440×900 viewport is used for page loading and the DOM/network transcript; then height expands once to document scrollHeight for full-document painting. --hide-scrollbars keeps layout width constant; the driver asserts both CTA and hint rectangles exactly match the requested viewport. Capture viewport dimensions are recorded too. --disable-gpu uses software compositing. Astro's unrelated dev toolbar is disabled using scratch-only XDG preferences. The fixed-dark site stays dark for L01/L02 light preference. No browser state injection, source edits, CSS animation override, T3 server or userdata is involved.

Diff0 marks every nonzero maximum absolute RGB-channel delta in saturated magenta on black, amplifying even 1/255. DiffT uses the same algorithm with a strict >16/255 maximum-channel threshold. Comparison uses original CSS-raster pixels, with no alignment, resizing or crop. Both whole-page images and diffs are linked below; section sheets supplement them.

Reproduction instructions · Runner · Browser driver · Fixtures with exact replacement SHA · Rebound source-derived matrix · Rendering environment · Source/tree hashes · Diff generator · Transcript validator · Validation results · Pixel audit · Cleanup record · Capture log · Before server log · After server log · Xvfb log · Inspection record · Inspection helper · Pixel audit log

Every visible difference / what else changed

  • M01/M02/M05/M06/L01: both labels change from “Download for macOS” to “Download for iOS”; the Apple icons remain. Both CTAs narrow and remain centered. The lower side-by-side alternate button moves horizontally at wide widths because the group gets narrower; narrow stacked alternate buttons keep their position. The command hint remains “⌘⏎”.
  • M03/M04/L02: both labels change from “Download for Linux” to “Download for Android”; both Linux icons disappear and no OS icon replaces them. CTA widths narrow slightly. Wide lower groups re-center, moving the adjacent alternate horizontally. “Ctrl ⏎” remains.
  • Desktop C01–C04, unknown U01/U02 and fallback F01/F02 labels/icons/hints/layouts are unchanged. Narrow controls are pixel-identical; wide controls have only the residual 1/255 pixels documented below. L01 and L02 remain the same fixed-dark visual state as their corresponding dark-preference profiles.
  • Residual pixels outside the CTA action regions: M06: 3 pixels, 0 above threshold; exact coordinates/RGB deltas in the linked pixel audit; C01: 3 pixels, 0 above threshold; exact coordinates/RGB deltas in the linked pixel audit; C03: 3 pixels, 0 above threshold; exact coordinates/RGB deltas in the linked pixel audit; F02: 3 pixels, 0 above threshold; exact coordinates/RGB deltas in the linked pixel audit. These are reported rather than claiming full zero-threshold equality outside the changed controls.
  • The residuals are exactly three pixels at (1301,724), (1302,725), (1302,727), maximum channel delta 1/255, on the transformed product image corner. Rasterization variability is an inference, not a proven source cause; no pixel outside CTA regions exceeds 16/255.

Exact CTA geometry, dimensions and counts; Pixel audit implementation. Hrefs are invisible and proven by the linked DOM/network logs: mobile after selects App Store / Play directly with zero release fetches; desktop success selects its fixed fixture asset; unknown and failed/missing assets retain Releases. The actual footer Download and nav Download remain /download; explicit footer store links stay unchanged. No installer or external store was activated.

Interaction and timing recordings

Recording index with steps and timestamps for every pair · Extended matrix · Audited row results: 34/34 · Independent proof audit: SUFFICIENT

Captured 34 requested recording rows as 47 matched pairs / 94 videos, including 13 supporting pairs that resolve lower-CTA timing and focus/resize/scroll framing. Headed Chromium on Xvfb, ffmpeg x11grab, identical scripts and inherited profiles at the exact before/after SHAs. All recordings were independently opened through temporal contact sheets and correlated with sidecars; 492 fresh contexts and 432 intercepted native navigation requests have zero oracle errors. Independent iPhone hero reproduction passed touch and real keyboard activation at both widths: four App Store requests, zero release fetches. Scripts, logs, hashes, cleanup records and reproduction footage are linked from the index and audit.

The recordings show existing macOS/Apple/Releases fallback before the page script executes on both revisions. Early activation then dispatches Releases; after initialization mobile selects its store without a release fetch. With JavaScript disabled, all profiles retain the default macOS/Releases markup. Webfont reflow also remains visible; these recordings do not establish no-flash or no-layout-shift behavior. Android's updated button has no platform glyph. The lower primary CTA is distinct from the actual footer Download link, which stays /download. Navigation is intercepted before external delivery, proving target selection rather than store landing or installation.

Recording row Before After
I01-android-footer-lower Before After
I01-android-hero Before After
I01-ipad-desktop-footer-lower Before After
I01-ipad-desktop-hero Before After
I01-iphone-footer-lower Before After
I01-iphone-hero Before After
I01-linux-footer-lower Before After
I01-linux-hero Before After
I01-mac-footer-lower Before After
I01-mac-hero Before After
I01-unknown-footer-lower Before After
I01-unknown-hero Before After
I01-windows-footer-lower Before After
I01-windows-hero Before After
I02-android Before After
I02-ipad-desktop Before After
I02-iphone Before After
I02-linux Before After
I02-mac Before After
I02-unknown Before After
I02-windows Before After
T01-android-early-activation Before After
T01-android-first-paint Before After
T02-ipad-desktop-early-activation Before After
T02-ipad-desktop-first-paint Before After
T02-iphone-early-activation Before After
T02-iphone-first-paint Before After
T03-android Before After
T03-ipad-desktop Before After
T03-iphone Before After
T03-linux Before After
T03-mac Before After
T03-unknown Before After
T03-windows Before After

Supporting pairs, complete step/timestamp tables and sidecars are in the recording index above.

Explicitly unverified: native Safari/WebKit on an actual iPhone.

Verification log
  • Tests: platform.test.ts 5 → 4; all pass via the marketing package task. Desktop-only detection fails the three mobile cases; faulty touch detection fails the iPad/Mac guards.
  • Scoped lint, formatting and marketing Astro check pass. No dependency patch. Fixed-literal regex scans are linear; malformed ~3000-token input measured ~0.04 ms per call.
  • Review round 1: A MERGE, B FIX_FIRST (tests skipped by CI). Added the package test task. Round 2: both MERGE, no remaining code findings.
  • Main merged by merge commit 69b0eb2c4c; four package tests pass again. Marketing files match the reviewed head; all evidence was recaptured and audited at this final head.
  • Proof: 16/16 static pairs, 80 images and 54 DOM/network transcripts inspected; independent M05 before/after recapture has zero pixel delta. Audit SUFFICIENT.
  • CI at final head: 30 reported checks green; Macroscope approves; CodeRabbit has no actionable findings.
  • Unverified: native Safari/WebKit on an actual iPhone. Requested Chromium interaction, timing and JS-disabled recording rows are now covered by the linked independent audit; marketing is the only touched surface.
  • Model and harness: Claude Opus 5.5 (tests, implementation, review); GPT-6.1 Sol (review, evidence, proof audit), through T3 Code with Codex coordination.
Original description by @saphid

Problem

The marketing homepage treats mobile user agents as desktop systems, offering an AppImage to Android visitors and a DMG to iPhone or iPad visitors.

Change

Detect Android and iOS before desktop platforms and send both homepage download buttons to the existing app-store URLs. Recognize iPad desktop mode using its Mac user agent and touch points. Preserve desktop download behavior.

Scope and approval

This is a maintainer-requested takeover of the existing focused marketing download bug fix. Based on the original work by @saphid.

Verification

Five platform-routing regressions pass, reduced from nine overlapping cases. Marketing typecheck, scoped lint, and format checks pass.

In desktop Chromium with a mobile viewport, a temporary proxy supplied navigator user-agent and touch-point values before the unmodified page scripts. Both hero and footer buttons selected the correct stores for Android, iPhone, and desktop-mode iPad, without fetching GitHub releases. The iOS Apple icon and command-key hint were browser-verified. macOS arm64 DMG, Linux AppImage, and Windows x64 EXE selection remained intact.

This did not test real Safari or native mobile browsers. Store URLs were inspected without opening stores or downloading files. The existing human product-eligibility review remains a landing gate.

iPhone user agent — before / after

Before: macOS download After: iOS store link
Before: iPhone user agent receives Download for macOS After: iPhone user agent receives Download for iOS

Android user agent — before / after

Before: Linux download After: Android store link
Before: Android user agent receives Download for Linux After: Android user agent receives Download for Android

Taken over with Claude Opus 5.5 (tests and review), Claude Fable 5.1 (implementation), and GPT-6.1 Sol (review) through T3 Code; coordinated with Codex.

juliusmarminge and others added 3 commits October 24, 2026 22:45
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Android visitors go to Google Play; iPhone and iPad visitors, including
iPadOS Safari's desktop Mac user agent, go to the App Store. Desktop
download routing is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The package lost its test script with the low-signal test cleanup, so CI's
change detection skipped the mobile store routing regression tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Oct 24, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 8e2e67e

Macroscope's review found this PR approvable — This is a focused marketing fix that routes mobile download CTAs to existing iOS and Android store listings while preserving desktop download behavior. The new platform detection is isolated and covered by tests, with no production configuration or sensitive-area changes.

No code changes detected at 69b0eb2. Prior analysis still applies.

You can add or adjust custom eligibility rules. Learn more.

@github-actions

github-actions Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 5.0 KiB 5.0 KiB 0 B (0.0%) 6.8 KiB ✅
Codex Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.2 KiB 1.2 KiB 0 B (0.0%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 20.9 KiB 20.9 KiB 0 B (0.0%) 29.3 KiB ✅
Codex Live turn messages 2 2 0 (0.0%) 8 ✅
Claude Total thread wire 5.0 KiB 5.0 KiB +7 B (+0.1%) 6.8 KiB ✅
Claude Thread snapshot wire 3.8 KiB 3.8 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB +7 B (+0.6%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 21.2 KiB 21.2 KiB 0 B (0.0%) 29.3 KiB ✅
Claude Live turn messages 2 2 0 (0.0%) 8 ✅

Baseline: c4fa462 · PR result: 69b0eb2 · Source CI: success

Scenario and decoded snapshot size

10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.

  • Codex decoded thread snapshot: 108.5 KiB
  • Claude decoded thread snapshot: 108.8 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 3cc31ed and 8e2e67e.

Files selected for processing: 4
  • apps/marketing/package.json
  • apps/marketing/src/lib/platform.test.ts
  • apps/marketing/src/lib/platform.ts
  • apps/marketing/src/pages/index.astro

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 2 remain after this review.

Walkthrough

The marketing site now detects mobile platforms, directs mobile download buttons to app stores, and uses the existing release flow for platforms without a store URL.

Changes: Marketing download flow

Layer / File(s) Summary
Platform detection and store mapping
apps/marketing/src/lib/platform.ts, apps/marketing/src/lib/platform.test.ts, apps/marketing/package.json
The shared helper classifies Android, iOS, Windows, macOS, and Linux platforms and returns store URLs for Android and iOS. Tests cover Android, iPhone, touch-enabled iPad, and macOS. The package adds a test script.
Homepage download integration
apps/marketing/src/pages/index.astro
The homepage uses the shared platform helper. When a mobile store URL exists, both download buttons use it and release lookup stops. Otherwise, the desktop release flow continues. The keyboard hint and Apple icon now account for iOS.

Priority: Normal

Estimated code review effort: 2 (Simple) | ~12 minutes

Change: Bug fix

Sequence Diagram(s)

sequenceDiagram
  participant Browser
  participant MarketingPage
  participant PlatformHelpers
  participant ReleaseAssets
  Browser->>MarketingPage: Load homepage
  MarketingPage->>PlatformHelpers: Detect platform from user agent and touch points
  PlatformHelpers-->>MarketingPage: Return platform
  MarketingPage->>PlatformHelpers: Look up mobile store URL
  PlatformHelpers-->>MarketingPage: Return store URL or null
  alt Store URL exists
    MarketingPage->>Browser: Set both download buttons to store URL
  else No store URL
    MarketingPage->>ReleaseAssets: Continue desktop release lookup
  end
Loading

Possibly related PRs

  • pingdotgg/t3code#18816: Changes the same marketing download behavior, including platform helpers, store routing, and iPad desktop-mode detection.

Suggested labels: bugfix, takeover, pr:in-progress, size:XS

Suggested reviewers: macroscopeapp, t3dotgg

Merge Risk: Minimal · up to 8e2e6

No download-routing issue is established that needs to be fixed before merging; the existing product-eligibility requirement still applies.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the primary change: routing mobile downloads to app stores.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The pull request description covers the problem, change, scope, approval context, verification results, evidence, limitations, and agent details. The original description includes all required templat…
Full details: Description check

Explanation

The pull request description covers the problem, change, scope, approval context, verification results, evidence, limitations, and agent details. The original description includes all required template headings. The scope section references the prior pull request and maintainer-requested takeover, although it does not include a direct approval comment link; this is non-critical because the focused bug fix and takeover context are explained.

Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@juliusmarminge juliusmarminge added bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed pr:in-progress A lead is working on this PR pr:needs-verification Reviewed and green; needs a run on a desktop, Android or iOS device and captures posted and removed pr:gate-failed A land gate failed pr:in-progress A lead is working on this PR labels Oct 24, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bugfix Fix PR opened by an issue lead; enters the PR loop pr:needs-verification Reviewed and green; needs a run on a desktop, Android or iOS device and captures posted size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant