Files
obsidian-vault/work/notes/webkit-macos-version-mapping.md
T

300 lines
12 KiB
Markdown
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Mapping Apple OS builds to WebKit source releases
tags: [webkit, safari, macos, ios, crash, ravel, reference]
created: 2026-10-06
updated: 2026-10-06
---
# Mapping Apple OS builds to WebKit source releases
## Purpose
This document explains how to map a WebKit crash on macOS or iOS to:
1. the exact Apple OS build;
2. the exact system WebKit binary by Mach-O UUID;
3. its `CFBundleVersion` and WebKit `FULL_VERSION`;
4. the closest public WebKit source tag;
5. the presence or absence of a source change.
The DuckDuckGo Apple browsers currently support macOS **12.3+** and iOS **15.0+**. The deployment targets are defined in `macOS/Configuration/Common.xcconfig` and `iOS/DuckDuckGo-iOS.xcodeproj/project.pbxproj` in the Apple browsers repository.
## Short answer
Use this chain for an exact mapping:
```text
OS version + OS build
-> WebKit Mach-O UUID from the crash report
-> matching binary and UUID in Ravel
-> WebKit CFBundleVersion from the OS or app telemetry
-> remove the platform SYSTEM_VERSION_PREFIX
-> WebKit FULL_VERSION
-> public source tag or release branch
-> inspect the released code for the fix
```
An OS major version identifies only a **WebKit release train**. It does not identify the exact WebKit revision because Apple updates WebKit in OS point and security releases.
## Version fields
| Field | Example | Meaning |
|---|---:|---|
| OS version | `macOS 27.0.1` | Marketing version |
| OS build | `26A434` | Exact Apple OS build; use this in Ravel |
| Mach-O UUID | `70BEE322-...` | Exact WebKit binary identity for one architecture |
| `CFBundleVersion` | `22625.1.29.11.28` | System framework build version |
| `SYSTEM_VERSION_PREFIX` | `22` | Platform/OS prefix added by Apple's production build |
| WebKit `FULL_VERSION` | `625.1.29.11.28` | Release version without the system prefix |
| Source tag | `WebKit-7625.1.29.11.28` | Candidate public source release |
| HTTP User-Agent | `AppleWebKit/605.1.15` | Frozen compatibility token; not usable for this mapping |
## Supported OS release trains
These tables map each supported OS major to its initial Safari/WebKit release train. Always use the exact-build workflow for a crash or API-availability decision.
### macOS 12.3+
| macOS | DDG support | Safari release | WebKit base `FULL_VERSION` | macOS prefix | Production bundle base | Public source-tag family |
|---|---:|---:|---:|---:|---:|---|
| 12 Monterey | 12.3+ | 15 | `612.1.27` | `17` | `17612.1.27` | `Safari-612.1.27.*` |
| 13 Ventura | Yes | 16 | `614.1.25` | `18` | `18614.1.25` | `WebKit-7614.1.25.*` |
| 14 Sonoma | Yes | 17 | `616.1.27` | `19` | `19616.1.27` | `WebKit-7616.1.27.*` |
| 15 Sequoia | Yes | 18 | `619.1.26` | `20` | `20619.1.26` | `WebKit-7619.1.26.*` |
| 26 Tahoe | Yes | 26 | `622.1.22` | `21` | `21622.1.22` | `WebKit-7622.1.22.*` |
| 27 Golden Gate | Yes | 27 | `625.1.29` | `22` | `22625.1.29` | `WebKit-7625.1.29.*` |
### iOS 15.0+
WebKit uses `SYSTEM_VERSION_PREFIX = 8` for iPhone-family SDKs. Therefore the iOS production bundle version is `8` concatenated with `FULL_VERSION`.
| iOS | DDG support | Safari release | WebKit base `FULL_VERSION` | iOS prefix | Production bundle base | Public source-tag family |
|---|---:|---:|---:|---:|---:|---|
| 15 | 15.0+ | 15 | `612.1.27` | `8` | `8612.1.27` | `Safari-612.1.27.*` |
| 16 | Yes | 16 | `614.1.25` | `8` | `8614.1.25` | `WebKit-7614.1.25.*` |
| 17 | Yes | 17 | `616.1.27` | `8` | `8616.1.27` | `WebKit-7616.1.27.*` |
| 18 | Yes | 18 | `619.1.26` | `8` | `8619.1.26` | `WebKit-7619.1.26.*` |
| 26 | Yes | 26 | `622.1.22` | `8` | `8622.1.22` | `WebKit-7622.1.22.*` |
| 27 | Yes | 27 | `625.1.29` | `8` | `8625.1.29` | `WebKit-7625.1.29.*` |
iOS versions 19–25 do not exist; Apple changed the public version number from 18 to 26.
## Exact builds verified in Ravel
Ravel is currently incomplete. A missing build means that Ravel does not index it, not that the OS lacks WebKit.
### macOS examples
| macOS | Build | WebKit UUID | `CFBundleVersion` | `FULL_VERSION` |
|---|---|---|---:|---:|
| 26.5.2 | `25F84` | `49B21D99-8716-31B8-8686-71B287325F1D` | `21624.2.5.11.8` | `624.2.5.11.8` |
| 26.6 | `25G72` | `B090AABF-9A3B-3110-9DA9-F0F40FCEC972` | `21624.4.5.11.5` | `624.4.5.11.5` |
| 26.6.1 | `25G76` | `B090AABF-9A3B-3110-9DA9-F0F40FCEC972` | `21624.4.5.11.5` | `624.4.5.11.5` |
| 26.6.2 | `25G83` | `844AF253-CAF6-3623-9DAD-A055C5274E62` | `21624.5.1.11.3` | `624.5.1.11.3` |
| 27.0.1 | `26A434` | `70BEE322-37EE-3B22-8012-4F76BA105C29` | `22625.1.29.11.28` | `625.1.29.11.28` |
| 27.2 beta | `26B5086k` | `6F6AB57E-1492-3950-9962-85B6AFD430A3` | `22625.2.4.1` | `625.2.4.1` |
| 27.2 beta 2 | `26B5091g` | `56B4AA44-CB66-3641-8B22-723C39B5BC6E` | `22625.2.5.11.1` | `625.2.5.11.1` |
| 27.2 beta 3 | `26B5101f` | `B32D7081-AE42-3A2E-ACBB-CF4D4BE4F296` | `22625.2.7.1` | `625.2.7.1` |
macOS 26.6 and 26.6.1 contain the same WebKit binary: both UUID and `CFBundleVersion` match.
### iOS examples
Ravel identifies iOS WebKit binaries and UUIDs, but its dyld-cache page does not expose the framework `Info.plist` value. Read `CFBundleVersion` at runtime or from an extracted IPSW before claiming an exact source release.
| iOS | Build | WebKit UUID |
|---|---|---|
| 26.6 | `23G71` | `7627FDAB-129E-32BB-A2AC-F0DC02853D4E` |
| 26.6.1 | `23G83` | `C39BD22C-3475-38AF-91BD-0B7574081011` |
| 26.6.2 | `23G90` | `C39BD22C-3475-38AF-91BD-0B7574081011` |
| 27.0.1 | `24A446` | `D12A79A6-98CB-323C-8F72-613AD0983BBC` |
| 27.2 beta | `24B5084k` | `1FD67A57-D91B-3B26-9F4F-91AB8299B6E7` |
| 27.2 beta 2 | `24B5089g` | `509D51AD-2CF9-3982-BFD5-81221D1B903D` |
| 27.2 beta 3 | `24B5099f` | `0566BF55-2DC4-34F6-B211-96FFAA0A37A4` |
iOS 26.6.1 and 26.6.2 contain the same WebKit binary UUID.
## Exact mapping procedure
### 1. Read the OS build and WebKit UUID
From an Apple crash report, record the OS version/build and the WebKit image UUID. Compare UUIDs without case or dashes, and match the architecture.
```bash
rg 'OS Version:|WebKit.*<' crash-report.crash
```
### 2. Find the binary in Ravel
Use the OS build and the correct binary path:
```text
macOS: /System/Library/Frameworks/WebKit.framework/Versions/A/WebKit
iOS: /System/Library/Frameworks/WebKit.framework/WebKit
```
Ravel URL pattern:
```text
https://ravel.dbg.re/binary?build=<OS_BUILD>&domain=dyld_cache&path=<URL_ENCODED_BINARY_PATH>
```
The Ravel UUID must equal the crash-report UUID. A matching version string without a matching UUID is weaker evidence.
### 3. Read `CFBundleVersion`
From app code on either platform:
```swift
import WebKit
let webKitBundleVersion = Bundle(for: WKWebView.self)
.object(forInfoDictionaryKey: "CFBundleVersion") as? String
```
On macOS, it can also be read without app changes:
```bash
defaults read /System/Library/Frameworks/WebKit.framework/Resources/Info CFBundleVersion
```
For iOS, log the runtime value on a test device or include it in crash/pixel metadata. Do not infer an exact iOS value from the same-numbered macOS release.
### 4. Remove `SYSTEM_VERSION_PREFIX`
Apple production builds concatenate the prefix and the WebKit version:
```text
CFBundleVersion = SYSTEM_VERSION_PREFIX + FULL_VERSION
```
| Platform | OS | Prefix |
|---|---|---:|
| iOS | All supported versions | `8` |
| macOS | 12 | `17` |
| macOS | 13 | `18` |
| macOS | 14 | `19` |
| macOS | 15 | `20` |
| macOS | 26 | `21` |
| macOS | 27 | `22` |
Example:
```text
22625.1.29.11.28 - prefix 22 -> 625.1.29.11.28
```
### 5. Resolve the public source release
For modern release trains, candidate tags use:
```text
WebKit-7<FULL_VERSION>
```
Example:
```text
625.1.29.11.28 -> WebKit-7625.1.29.11.28
```
The 612 train is an older naming exception:
```text
612.1.27.* -> Safari-612.1.27.*
```
Check exact public tags and release branches:
```bash
git ls-remote --tags https://github.com/WebKit/WebKit.git 'WebKit-7625.1.29*'
git ls-remote --heads https://github.com/WebKit/WebKit.git 'safari-7625*'
```
An adjacent tag is only a bound, not an exact match. Apple may publish a binary before publishing the corresponding source tag.
### 6. Verify the fix in released source
Inspect the changed code in the candidate tag. This is stronger than checking one commit SHA because Apple may cherry-pick the change under a different SHA.
For the certificate-info crash discussed below:
```bash
git show <TAG>:Source/WebKit/UIProcess/WebFrameProxy.h \
| rg 'commitCertificateInfo'
```
Old signature:
```cpp
void commitCertificateInfo(const URL&);
```
Fixed signature from `318982@main`:
```cpp
void commitCertificateInfo(const URL&, bool hasCertificateInfo);
```
### 7. When the exact source tag is unavailable
Record the evidence level explicitly:
1. UUID + `CFBundleVersion`: exact binary and release version are known.
2. Symbols or disassembly: a specific ABI or behavior can be proven in the binary.
3. Reproduction on the exact OS build: the bug can be proven present or absent.
Safari Technology Preview is a separate build. Its version does not prove the version of system WebKit.
## Current certificate-info crash
The crash on macOS 27.0.1 maps as follows:
```text
macOS: 27.0.1 (26A434)
Crash UUID: 70BEE322-37EE-3B22-8012-4F76BA105C29
Ravel UUID: 70BEE322-37EE-3B22-8012-4F76BA105C29
CFBundleVersion: 22625.1.29.11.28
Prefix: 22
FULL_VERSION: 625.1.29.11.28
Candidate tag: WebKit-7625.1.29.11.28
```
The exact `.11.28` source tag is not public as of 2026-10-06; `.11.27` is public. The crash symbol and the `WebKit-7625.1.29` source family both show the old one-argument signature. Therefore the fix is absent from macOS 27.0.1.
Ravel identifies macOS 27.2 beta binaries as `625.2.4.1`, `625.2.5.11.1`, and `625.2.7.1`. Public `WebKit-7625.2.*` tags are not available as of 2026-10-06. The fix landed in `318982@main` and Safari Technology Preview 251, so macOS 27.2 is a candidate for the first fixed system release, but source inclusion is not yet proven.
## DuckDuckGo telemetry gap
Current pixels do not include the exact system WebKit `CFBundleVersion`. The HTTP User-Agent cannot fill this gap because Apple returns the frozen `AppleWebKit/605.1.15` compatibility token.
Add one field to relevant crash and WebKit failure telemetry:
```text
webkit_build=22625.1.29.11.28
```
Populate it from `Bundle(for: WKWebView.self).CFBundleVersion`. This makes OS-build-to-WebKit correlation deterministic on both macOS and iOS.
## Sources
- [WebKit source repository](https://github.com/WebKit/WebKit)
- [Current WebKit version configuration](https://github.com/WebKit/WebKit/blob/main/Configurations/Version.xcconfig)
- [Safari 15 / WebKit 612 version configuration](https://chromium.googlesource.com/external/github.com/WebKit/webkit/+/refs/tags/Safari-612.1.27/Source/WebKit/Configurations/Version.xcconfig)
- [Safari 16 / WebKit 614 version configuration](https://chromium.googlesource.com/external/github.com/WebKit/webkit/+/refs/tags/WebKit-7614.1.25/Source/WebKit/Configurations/Version.xcconfig)
- [Safari 17 / WebKit 616 version configuration](https://github.com/WebKit/WebKit/blob/WebKit-7616.1.27/Configurations/Version.xcconfig)
- [Safari 27 / WebKit 625 version configuration](https://github.com/WebKit/WebKit/blob/WebKit-7625.1.29/Configurations/Version.xcconfig)
- [Ravel binary catalogue](https://ravel.dbg.re/browse)
- [MDN Safari release metadata](https://github.com/mdn/browser-compat-data/blob/main/browsers/safari.json)
- [Safari release notes](https://developer.apple.com/documentation/safari-release-notes)
- [WebKit commit 318982@main](https://commits.webkit.org/318982@main)
- [Safari Technology Preview 251](https://webkit.org/blog/18194/release-notes-for-safari-technology-preview-251/)
## Limits
- One OS major contains multiple WebKit updates; use the exact OS build for conclusions.
- Ravel is in beta and does not index every historical Apple build.
- Intel and Apple Silicon binaries may have different UUIDs.
- An exact public tag may appear after Apple ships the binary.
- Verify released code, not only commit ancestry, because fixes can be cherry-picked.