Provenance refreshed for published replacement [#24577](https://github.com/pingdotgg/t3code/pull/24577). Approved 16-row content retained; historical plan claims below remain history. Fresh capture results are in the final evidence index.

# Proof audit pass 1: marketing mobile downloads

PR: [#18816](https://git.cafe/pingdotgg/t3code/pulls/18816) ([GitHub #18816](https://github.com/pingdotgg/t3code/pull/18816)). Original fork branch `saphid/t3code:t3code/sweep/marketing-mobile-downloads` at [707797ab](https://github.com/saphid/t3code/commit/707797ab66291552c8aeca4c8eea7932e21c6ff0). Replacement `takeover/pr-18816` at [69b0eb2c](https://github.com/pingdotgg/t3code/commit/69b0eb2c4c9b20210a40c1fad35977ba056aa946). Before = current origin/main merge-base [c4fa4629](https://github.com/pingdotgg/t3code/commit/c4fa4629eb645b95aae2beef56c70f705b736049).

Status: original source-derived proof plan, rebound to replacement metadata-only head. Capture execution and observed coverage are reported in the companion evidence index; the planning restrictions below describe pass 1, not the separately authorized capture pass. Original pass-1 status: planning proof only. No browser, server, screenshot, test runner, edit to checkout, push, comment, or watch performed. All expected results below are SOURCE-DERIVED, not observed. Every capture remains unverified until pass 2. Read `/home/ubuntu/t3code-ops/docs/EVIDENCE.md`. Scratch is outside the checkout.

## Diff coverage and callers

Full supplied-baseline diff: three files, 86 additions / 13 deletions. New `src/lib/platform.ts` and its four-case test; `src/pages/index.astro` changes detection, init routing, hint predicate and iOS icon CSS. No marketing dependencies or other pages change. The original contributor revision is provenance, not the before image. The replacement broadens desktop-Mac matching from Macintosh to Mac and moves Windows ahead of Mac/touch; use the replacement code for expectations.

- [Platform helper](https://github.com/pingdotgg/t3code/blob/69b0eb2c4c9b20210a40c1fad35977ba056aa946/apps/marketing/src/lib/platform.ts#L10): Android first; explicit iPhone/iPad/iPod; Windows; Mac with touch >1 versus <=1; Linux; unknown/null. Mobile URL selection returns App Store / Play / null.
- [Only production caller](https://github.com/pingdotgg/t3code/blob/69b0eb2c4c9b20210a40c1fad35977ba056aa946/apps/marketing/src/pages/index.astro#L442): homepage `/`, init invoked once. Reads navigator values, sets html data-platform and BOTH labels, adjusts the decorative keyboard hint, sets BOTH hrefs and returns for stores. Desktop success selects arm64 DMG / x64 EXE / x86_64 AppImage; missing assets retain markup fallback; rejected release lookup sets fallback. Null platform returns before any changes or fetch.
- [Hero](https://github.com/pingdotgg/t3code/blob/69b0eb2c4c9b20210a40c1fad35977ba056aa946/apps/marketing/src/pages/index.astro#L62): #download-btn, #download-label, three icons, unchanged explicit mobile links/source link.
- [Lower CTA](https://github.com/pingdotgg/t3code/blob/69b0eb2c4c9b20210a40c1fad35977ba056aa946/apps/marketing/src/pages/index.astro#L398): #cta-download-btn, #cta-download-label, same three icons, unchanged /download alternate. This is the requested footer download CTA. Actual Layout footer Download remains /download; iOS app / Android app remain explicit stores.
- [Git marketing panel](https://github.com/pingdotgg/t3code/blob/69b0eb2c4c9b20210a40c1fad35977ba056aa946/apps/marketing/src/pages/index.astro#L303): #pr-button-kbd is a decorative span, not an actionable keyboard binding. Capture it too. iOS deliberately retains command symbol; Android/Win/Linux use Ctrl.
- [Icon CSS](https://github.com/pingdotgg/t3code/blob/69b0eb2c4c9b20210a40c1fad35977ba056aa946/apps/marketing/src/pages/index.astro#L651): iOS shares Apple; Android has no icon rule, so all OS icons hidden. Record that visible difference rather than inventing an Android icon.

No native mobile client, Electron shell, providers, wire contracts, auth, settings, app data, relay or tunnel paths are touched. Do not start the T3 app server or access ~/.t3. `/download`, `/95`, legal pages do not import the helper; no separate page fixture is warranted. Their homepage links are controls.

## Minimum static capture matrix

Each row is ONE matched before/after full-page pair on the real marketing homepage. Capture at the stated viewport; full-page raster retains that CSS width. It must include hero, git panel and lower CTA + real footer. Add full-viewport views of these sections if the uploaded full-page image is unreadable; crops alone do not replace whole-surface evidence. For each row inspect both CTA hrefs independently, labels, computed visible icons, keyboard hint, data-platform, and release network events. Keep the pointer off the CTAs. All rows use reduced motion so unrelated continuously moving endorsements and floating marks do not swamp diffs.

| ID | Browser profile | CSS viewport | Preference / actual theme | Release input | Affected | Expected before → after | Evidence |
|---|---|---|---|---|---|---|---|
| M01 | iphone | 390×844 | dark / dark | success | YES | mac → ios; macOS → iOS; Apple stays; ⌘⏎ stays; DMG → App Store | full-page still pair + DOM/network log |
| M02 | iphone | 1440×900 | dark / dark | success | YES | Same routing, wide layout | full-page still pair + DOM/network log |
| M03 | android | 390×844 | dark / dark | success | YES | linux → android; Linux → Android; Linux icon → no OS icon; Ctrl ⏎ stays; AppImage → Play | full-page still pair + DOM/network log |
| M04 | android | 1440×900 | dark / dark | success | YES | Same routing, wide layout | full-page still pair + DOM/network log |
| M05 | ipad-desktop | 390×844 | dark / dark | success | YES | Mac UA + touch=5: mac → ios; DMG → App Store; Apple/⌘⏎ retained | full-page still pair + DOM/network log |
| M06 | ipad-desktop | 1440×900 | dark / dark | success | YES | Desktop-mode iPad branch in wide desktop layout | full-page still pair + DOM/network log |
| C01 | mac | 1440×900 | dark / dark | success | control | mac/macOS/Apple/⌘⏎/arm64 DMG unchanged | full-page still pair + DOM/network log |
| C02 | mac | 390×844 | dark / dark | success | control | Narrow desktop control; longest platform label + Apple icon | full-page still pair + DOM/network log |
| C03 | windows | 1440×900 | dark / dark | success | control | win/Windows/Windows icon/Ctrl ⏎/x64 EXE unchanged | full-page still pair + DOM/network log |
| C04 | linux | 1440×900 | dark / dark | success | control | linux/Linux/Linux icon/Ctrl ⏎/x86_64 AppImage unchanged | full-page still pair + DOM/network log |
| U01 | unknown | 390×844 | dark / dark | success | control | No data-platform; macOS/Apple/⌘⏎/releases fallback; no release request | full-page still pair + DOM/network log |
| U02 | unknown | 1440×900 | dark / dark | success | control | Same unknown fallback, wide layout | full-page still pair + DOM/network log |
| L01 | iphone | 390×844 | light / dark | success | YES, preference control | Light preference still renders fixed dark site; compare with M01 | full-page still pair + DOM/network log |
| L02 | android | 1440×900 | light / dark | success | YES, preference control | Light preference still renders fixed dark site; compare with M04 | full-page still pair + DOM/network log |
| F01 | windows | 390×844 | dark / dark | missing-assets | control | Windows label/icon/Ctrl ⏎; releases href retained when no matching asset | full-page still pair + DOM/network log |
| F02 | linux | 1440×900 | dark / dark | network-error | control | Linux label/icon/Ctrl ⏎; releases href restored on rejected fetch | full-page still pair + DOM/network log |

**Minimum: 16 full-page pairs = 32 stills, plus two diff images per pair (zero threshold amplified; threshold 16/255 per RGB channel, explicitly state algorithm).** Six mobile pairs cover the three affected UA paths at both required widths; four desktop controls cover each asset/icon/hint path and narrow long-label layout; two unknown controls cover both widths; two light-preference rows prove the unsupported-theme statement at both widths; two fallback rows cover distinct no-match and catch control flow. Dark-only CSS means a full light cross-product would repeat the exact render. For unchanged Windows/Linux narrow success, use C02 narrow geometry + F01 narrow Windows + C04 Linux icon; those combinations need DOM routing checks, not additional full-page pairs. No automatic Cartesian multiplication by themes/UA aliases/network states.

Reproducible input sidecar: [fixtures.json](https://gh-file-drop-api-prod-mi5fy3sowv63ufte.pinglabs.workers.dev/f/34efc44d2c79b9c4/fixtures.json). It contains exact UA/touch/device profiles, viewport/theme rows, fixed release payload, and explicit iPad/iPod alias inputs.

## Exact environment and seeding requirements

Headed Chromium on Xvfb, with browser version, executable, automation tool/version and DISPLAY recorded. Use an approved browser tool capable of creating a fresh context with these UA/device settings before first navigation. iPhone Safari and iPad Safari here mean Safari USER-AGENT/device emulation in Chromium, not WebKit or real Safari; state that limitation on every relevant capture. Do not relabel it native Safari proof. Desktop controls use desktop Chrome UAs. Android uses Chrome UA. Record effective navigator.userAgent, navigator.maxTouchPoints, UA-CH if present, touch/coarse-pointer media state, isMobile setting, devicePixelRatio, innerWidth/innerHeight, visualViewport scale and document scrollWidth from the actual page.

Set viewport as matrix, zoom 100%, visual viewport scale 1, default font scaling 100%, no OS accessibility scaling, no forced text-size-adjust CSS. Load bundled DM Sans and JetBrains Mono; await document.fonts.ready and image decoding. Mobile font autosizing stays whatever this Chromium/device emulation naturally uses; record computed font size at both labels and the hint. Phone device settings and DPR remain identical before/after at a given row. iPad desktop mode intentionally uses isMobile=false with touch points=5; viewport 390 is a narrow-window stress fixture, not a physical iPad portrait claim. Width 1440 with phone UA is a wide-layout stress fixture, not physical phone dimensions.

| Profile | maxTouchPoints | isMobile | hasTouch | DPR | Exact userAgent |
|---|---|---|---|---|---|
| iphone | 5 | True | True | 3 | `Mozilla/5.0 (iPhone; CPU iPhone OS 18_6 like Mac OS X) AppleWebKit/605.1.15 Version/18.6 Mobile/15E148 Safari/604.1` |
| android | 5 | True | True | 3 | `Mozilla/5.0 (Linux; Android 15; Pixel 9) AppleWebKit/537.36 Chrome/140.0.0.0 Mobile Safari/537.36` |
| ipad-desktop | 5 | False | True | 2 | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15) AppleWebKit/605.1.15 Version/18.6 Safari/605.1.15` |
| mac | 0 | False | False | 1 | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36` |
| windows | 0 | False | False | 1 | `Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36` |
| linux | 0 | False | False | 1 | `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36` |
| unknown | 0 | False | False | 1 | `ProofAuditUnknown/1.0` |

A device preset that only sets hasTouch may report maxTouchPoints=1 and MISS the touched iPad branch. Use browser/CDP touch emulation with maxTouchPoints=5 and verify it on the actual page before accepting the fixture. Do not override window.navigator via a proxy, inject a substitute routing function, set data-platform/labels/hrefs by hand, or render a synthetic harness. UA/touch are browser environment inputs, not fake application state.

The real page is static marketing data; there is no database seed or login. Navigate `/` on real Astro marketing dev servers at exact SHAs. This pass cannot prepare a baseline checkout or launch a server because the authorized checkout is read-only. Capturer must obtain separately authorized baseline/head execution directories; do not checkout/reset this directory. The marketing dev npm script runs `stage-install-scripts.mjs` (copies installer scripts into public), and Astro generates caches/types, so serving directly from this read-only checkout is not compliant. Use writable execution copies established by the capture owner, no edits to application source. Record server origin, command and exact git/tree SHA per side. Default marketing port is 4173; use two distinct unoccupied loopback ports, not the root `vp run dev` command.

Release seeding: fixtures.json contains a fixed representative GitHub latest-release JSON with all three named asset suffixes. Intercept ONLY the real page fetch to the GitHub latest-release endpoint at the browser network boundary and serve the same recorded JSON on each side. This is external-data seeding, not a replacement app. Mark fixture asset URLs as proof-only; do not download these nonexistent files. In missing-assets mode serve the same metadata with assets=[]; network-error mode reject that fetch. Fresh context/sessionStorage for every row and side prevents stable-release cache leakage. Do not prepopulate sessionStorage to bypass the actual fetch path. Also log no latest-release request for after mobile rows and unknown rows. If using live releases instead, save the exact response once and replay it to both sides, with real asset URLs; never let latest change between shots.

Use identical fixed Date/year on both sides if needed; this page includes a footer year. Preserve identical scroll positions and wait for settled DOM hrefs AND fonts/images before static capture. A network-idle heuristic alone is insufficient. With reduced-motion=reduce the page does not keep drifting; document this setting. No source modifications or whole-page CSS animation overrides. Keep capture driver and external response data outside checkout and upload/link them with the evidence so another auditor can reproduce the inputs. fixtures.json is the declarative input contract, not a browser implementation.

## Hero and lower-CTA target oracle

Every target in this table applies independently to #download-btn AND #cta-download-btn; assert equality but read both. These are expected values after settled load, not captures.

| Profile / release state | Before href | After href | After release request? |
|---|---|---|---|
| iPhone; explicit iPad/iPod; desktop-mode iPad | [arm64 DMG fixture](https://github.com/pingdotgg/t3code/releases/download/proof-pass1-fixed/T3-Code-proof-arm64.dmg) | [App Store](https://apps.apple.com/us/app/t3-code-remote-claude-more/id6787819824) | NO |
| Android | [AppImage fixture](https://github.com/pingdotgg/t3code/releases/download/proof-pass1-fixed/T3-Code-proof-x86_64.AppImage) | [Google Play](https://play.google.com/store/apps/details?id=com.t3tools.t3code) | NO |
| macOS success | [arm64 DMG fixture](https://github.com/pingdotgg/t3code/releases/download/proof-pass1-fixed/T3-Code-proof-arm64.dmg) | [arm64 DMG fixture](https://github.com/pingdotgg/t3code/releases/download/proof-pass1-fixed/T3-Code-proof-arm64.dmg) | YES |
| Windows success | [x64 EXE fixture](https://github.com/pingdotgg/t3code/releases/download/proof-pass1-fixed/T3-Code-proof-x64.exe) | [x64 EXE fixture](https://github.com/pingdotgg/t3code/releases/download/proof-pass1-fixed/T3-Code-proof-x64.exe) | YES |
| Linux success | [AppImage fixture](https://github.com/pingdotgg/t3code/releases/download/proof-pass1-fixed/T3-Code-proof-x86_64.AppImage) | [AppImage fixture](https://github.com/pingdotgg/t3code/releases/download/proof-pass1-fixed/T3-Code-proof-x86_64.AppImage) | YES |
| Unknown | [Releases](https://github.com/pingdotgg/t3code/releases) | [Releases](https://github.com/pingdotgg/t3code/releases) | NO |
| Desktop missing match / rejected fetch | [Releases](https://github.com/pingdotgg/t3code/releases) | [Releases](https://github.com/pingdotgg/t3code/releases) | YES |
| iOS with release endpoint unavailable | [Releases](https://github.com/pingdotgg/t3code/releases) | [App Store](https://apps.apple.com/us/app/t3-code-remote-claude-more/id6787819824) | NO |
| Android with release endpoint unavailable | [Releases](https://github.com/pingdotgg/t3code/releases) | [Google Play](https://play.google.com/store/apps/details?id=com.t3tools.t3code) | NO |

Before iOS is recognized as Mac; Android as Linux. Before missing/rejected release means releases fallback even though the old platform label/icon remain. All initial markup hrefs are Releases on both revisions. Store links assigned by this diff retain the original same-tab anchor semantics; no new target attribute. Actual Layout footer Download and nav Download and lower alternate stay `/download`; hero iOS / Android and footer iOS app / Android app stay their explicit store links in both revisions.

## Collapsed branch fixtures and temporal/interaction rows

All rows below still require a real-page DOM/network transcript on both SHAs; they are collapsed from extra full-page screenshots only where the visible result is already represented. Never mark them captured from helper unit tests.

| ID | Real-page input / sequence | Affected | Expected / collapse rationale | Required medium |
|---|---|---|---|---|
| B01 | Explicit iPad UA, then iPod UA, touch=5, 390 dark | YES | Same explicit iOS return as iPhone. Both contain Mac OS X so base mac → iOS. M01 represents the exact visual state. Include exact UA strings in transcript. | DOM/href/icon/network log; no extra still |
| B02 | desktop Mac UA touch=1, then touch=0; 390 dark | control | Both <=1 remain mac; M05 touch=5 covers >1. C02 represents visual state. | DOM/href log |
| B03 | Windows and Linux success each at 390 dark | control | Distinct targets asserted; icon/labels already captured at 1440, narrow layout represented by C02/F01. | DOM/href log |
| B04 | iPhone then Android, latest-release endpoint rejected, 390 dark | YES | After never requests endpoint; store href still selected. Before falls back to Releases. M01/M03 represent visual output; href difference is invisible and must be logged. | DOM/network log |
| B05 | Desktop success reload in same session | control | First load fills t3code-stable-release cache; second reuses it; final output equals C01/C03/C04. No change in helper cache logic. | DOM/network log |
| T01 | Fresh Android 390 load, optional controlled delay of before release response | YES | Initial HTML macOS/Apple/Releases → Linux/Linux-icon/Releases → AppImage before; after Android/no-icon/Play in synchronous init. No new timed UI or handler. Minimum settled stills M03 + href logs prove settled routing only. | If claiming transition/no flash/early-tap safety, short matched recordings from navigation through settled load; otherwise mark transient behavior unverified |
| T02 | Fresh iPhone or desktop-mode iPad 390 load with same delay | YES | Initial markup macOS/Releases becomes iOS/store after; old version waits for desktop release. Same limitation as T01. | Recording or timed frame sequence required for temporal claims; otherwise static routing only |
| I01 | Hero and lower CTA activation; pointer/touch and keyboard activation | target changed | Native anchors have no changed click/keydown handler. Settled href inspection is sufficient for this static routing audit; do not navigate to external stores or download installers merely to prove href. | No extra video in minimum. Any claim of actual activation/navigation needs short recording/sequence with destination request logged and blocked before download |
| I02 | Hover/focus/active/scroll/resize | unchanged control | Shared button styles, layout media rules and scroll/motion handlers are unchanged. Hint is a span, not a keyboard shortcut. 390/1440 represent narrow/wide layouts; <=340 floating-mark sizing and 820/960/1180 intermediate layouts add no changed conditional. | Not a new interaction fixture; if resizing is demonstrated, record it, do not substitute a single still |
| T03 | JavaScript disabled | unchanged control | Both revisions render default macOS/Apple/Releases and command hint. This is not unknown-UA with JS. Optional smoke log; JS-disabled experience not part of new routing proof. | Explicitly unverified if omitted; no required extra pair |

No recording is mandatory for a claim restricted to static, settled-load routing: code changes native anchor destinations and synchronous labels/icon selection, with no new event handler or timing control. T01/T02 enumerate the timing paths and set the boundary of that claim. If the capture report discusses transitions, first-tap behavior, hover/keyboard navigation or animation smoothness, those rows become mandatory recordings/sequences, and reduced-motion stills cannot prove them.

No separate loading spinner, empty page, error panel, user account counts, translation/long-name input, custom label prop, or conditional caller exists here. Missing DOM null-guards are defensive only: real homepage always includes both anchors, labels and hint. Removing elements to force guards would violate real-page evidence requirements. Asset absence/catch are the real data-dependent fallback paths and are included.

## Pass-2 acceptance and visible-change checklist

For every M/C/U/L/F row provide Before | After | zero-threshold amplified diff | thresholded diff, exact SHAs, dimensions/theme/device settings, and DOM/network sidecar. Whole page and required sections must be readable. Record all visible changes: iPhone/iPad labels in both CTAs; Android labels in both CTAs and removal of Linux icons; any CTA width/reflow or neighboring displacement; Apple retained for iOS; command hint retained for iOS; unchanged desktop/unknown controls. Hrefs are invisible: screenshots alone cannot prove them. Every unplanned pixel change requires explanation; no blanket “nothing else changed” based only on thresholded diffs.

Current PR body screenshots and proxy-injected navigator claims predate this proof plan and do not establish replacement-head coverage. Live forge source is still the original fork SHA; local takeover head is a separate published revision. Pass 2 must compare captures to the supplied replacement SHA, not to the PR badge. Existing bot approval/product-eligibility comments are not proof of these captures. No merge-readiness verdict in pass 1.

## FRICTION (current provenance)

The original planning pass and prior SUFFICIENT audit are history only. Published replacement [#24577](https://github.com/pingdotgg/t3code/pull/24577) now binds to the final head above. The approved matrix rows and branch checks are unchanged. Current capture limitations and friction are reported in the fresh evidence index; this plan is not an audit of those captures.
