# 第一章：综述与版本边界 (/docs/v4/01)

## 1.1 版本边界声明 [#11-版本边界声明]

### 1.1.1 应用版本 [#111-应用版本]

从 `/Applications/Claude.app/Contents/Resources/app.asar` 内解出的 `package.json` 原文：

```json
{
  "name": "@ant/desktop",
  "version": "3.6556.2",
  "productName": "Claude"
}
```

**证据链**：
- 文件位置：ASAR 根目录 `package.json`，`size = 1835`（REA 6.8.0 生成的取证包记录）
- ASAR Header 结构：偏移 `0..16` 为长度头，`uint32LE@12` 给出 JSON 头长度；JSON 头从偏移 16 开始；文件数据区起始 = `16 + headerSize`
- 交叉验证：`/Applications/Claude.app/Contents/Info.plist` 的 `CFBundleShortVersionString = 3.6556.2`，`CFBundleVersion = 3.6556.2`

### 1.1.2 ASAR 根摘要 [#112-asar-根摘要]

```
sha256 = b2dfbbb40325d978dcb7561ad12a6f9bc199f8f46b7d3d2897af74ce8965d68a
```

REA 取证包 `artifacts[0].digest.sha256` 与 `shasum -a 256` 直接计算结果一致，**同一次取证可复现**。

REA 取证包标识：

```
evidence_id = ev_77dc39e02692fc4337a916c2321df1f1cfef85c3f30a034593655fa2eea55303
operation   = analyze_javascript_application
authority   = shipped-artifact
confidence  = derived
```

### 1.1.3 ASAR 内部规模 [#113-asar-内部规模]

```json
{
  "relevant_files": 572,
  "parsed_javascript_files": 546,
  "skipped_javascript_files": 7,
  "parse_failures": 0,
  "invalid_utf8_files": 0,
  "text_bytes_read": 42966700,
  "visited_ast_nodes": 6621556,
  "findings": 10872,
  "modules": 72,
  "nested_asar_containers": 0
}
```

**证据**：`records[0].normalized_result.statistics`

独立复核：直接用 Node 解析 ASAR header，条目总数 **629**（含非 JS 文件如 CSS/HTML/JSON/node）。572 是 REA 判定为「相关」的子集。

### 1.1.4 进程与窗口拓扑（实测） [#114-进程与窗口拓扑实测]

**7 个 renderer 入口**（ASAR 内 `.vite/renderer/` 下的目录）：

```
about_window
buddy_window
file_viewer
find_in_page
local_exec_consent
main_window
quick_window
```

**证据**：`Object.keys(asarHeader.files[".vite"].files.renderer.files)` → 上述 7 项。

但 REA `summary.browser_windows = 5`。两者不矛盾：

- `5` 统计的是「代码里 `new BrowserWindow` 创建的不同窗口」
- `7` 是「磁盘上的 renderer HTML 入口数」

差的 2 个（`file_viewer`、`local_exec_consent`）由其他机制打开，不走 `new BrowserWindow`。

**⚠️ 本节的可信度限制**：主进程文件 `.vite/build/index.pre.js` 在 REA 取证中 `parse_status = "partial"` 且 `static_analysis` 字段缺失（见 1.2），因此「5 个 BrowserWindow」来自 REA 对可解析部分的汇总，**不是对主进程完整代码的直接计数**。详见 [第二章 2.3](/docs/v4/02)。

---

## 1.2 取证覆盖度与不可解项 [#12-取证覆盖度与不可解项]

REA 取证包 `records[0].normalized_result.limitations` 共 **1064 条**。按原因归并：

| 原因 | 条数 | 原文（节选） |
| :--- | ---: | :--- |
| 语义分析未启动 | 512 | `The parent reserved its remaining result capacity for static observations; semantic analysis of <file> was not started` |
| 语义图超预算 | 10 | `Semantic graph for <file> exceeds the parent's remaining result budget; static and module facts were retained` |
| 工作进程资源约束 | 7 | `Owned JavaScript worker … resource constraint` |
| 完整性冲突 | 8 | `Artifact integrity metadata contradicts observed bytes at <path>` |
| 其他（内联脚本、别名上限等） | 527 | 逐条不同 |

**去重后的受约束文件数：532**（`[...new Set(limitations.filter(l=>l.includes("Resource constraint")).map(l=>l.split(":")[0]))].length`）。

### 1.2.1 被截断的核心文件 [#121-被截断的核心文件]

```
.vite/build/mainView.js
.vite/build/mainWindow.js
.vite/build/quickWindow.js
.vite/build/aboutWindow.js
.vite/build/heavy-work-worker/dist-CI9lzb1v.js
.vite/build/heavy-work-worker/heavyWorkWorker.js
```

**这直接导致本文的一个重要结论**：REA 主报告中的 `ipc.main_handlers = 0` **不能直接采信**，必须绕过 REA 直接读字节验证。第二章完成了这项验证，结论是**该零值成立，但原因与 REA 的推断不同**。

### 1.2.2 六个结构性零值 [#122-六个结构性零值]

```json
{
  "ipc.main_handlers": 0,
  "ipc.paired_renderer_transmissions": 0,
  "ipc.ambiguous_renderer_transmissions": 0,
  "preload_entrypoints": 0,
  "resolved_utility_entrypoints": 0,
  "native_addon_bindings": 0,
  "resolved_native_addon_bindings": 0
}
```

**证据**：`records[0].normalized_result.summary`。

本文对其中三个做了字节级复核（第二章）：

| 零值 | 复核结论 | 复核方法 |
| :--- | :--- | :--- |
| `ipc.main_handlers = 0` | ✅ **成立** | 主进程仅 6 个 `ipcMain.on(t.createKey(...))`，全部属于 Sentry SDK 命名空间 |
| `preload_entrypoints = 0` | ✅ **成立** | 全 ASAR 无 preload 命名文件；preload 路径由 `registerPreloadScript` 运行时拼接 |
| `native_addon_bindings = 0` | ⚠️ **部分成立** | 磁盘有 5 个 `native-addon` 节点，但其中 8 处完整性冲突，REA 拒绝建立可信绑定 |

其余三个零值本文**不复核、不推断**，标注为 `unknown`。

### 1.2.3 语义图的族级覆盖度 [#123-语义图的族级覆盖度]

`records[0].normalized_result.semantic_graph.coverage.families` 全部 12 个族状态均为 `partial`：

| family | retained_relations | unknown_ids 数量 |
| :--- | ---: | ---: |
| data-flow | 51995 | 24800 |
| object-flow | 5461 | 21917 |
| closure | 16153 | 531 |
| call-flow | 11047 | 8157 |
| promise-ownership | 295 | 715 |
| event | 121 | 626 |
| boundary | 54 | 537 |
| request | 48 | 543 |
| timer | 15 | 544 |
| configuration | 1 | 531 |
| **child-process** | **0** | 531 |
| **resource-lifecycle** | **0** | 531 |

全局 unknown 节点 **59963** 个。

**含义**：本文凡是涉及「数据流」「对象流」「资源生命周期」的推断都必须显式标注为不可靠。本文因此**只采信可直接从字节读出的静态事实**（token 值、keyframes 定义、选择器结构、字面量字符串）。

---

## 1.3 v2 → v3 迁移影响面 [#13-v2--v3-迁移影响面]

本节给出**可直接执行的迁移判定**，每条附证据。

### 1.3.1 必须修改的令牌值 [#131-必须修改的令牌值]

| 令牌 | open-claude-ui 现值 | 3.6556.2 实测值 | 判定 |
| :--- | :--- | :--- | :--- |
| `--cds-clay-emphasized` | `var(--cds-clay-hover)`（light `#cc5a36` / dark `#e08264`） | **`#c6613f`**（2 处定义：`:root` 与 `.cds-root`，值相同，无暗色覆盖） | ❌ **必须改** |

**证据**：

```bash
grep -c "\--cds-clay-emphasized:" MainWindowPage-BjVtjJFx.css     # → 2（:root 与 .cds-root，值均为 #c6613f）
grep -c "\--cds-clay-emphasized:" MainWindowPage.css | grep dark # 反模式，见下
# 无暗色覆盖的验证方式：
grep -o "data-mode=dark[^{]*{[^}]*--cds-clay-emphasized" MainWindowPage-BjVtjJFx.css | wc -l   # → 0
grep -o  "\--cds-clay-emphasized:[^;}]*" MainWindowPage-BjVtjJFx.css  # → --cds-clay-emphasized:#c6613f
```

原 CSS 中的完整上下文（相邻令牌，用于确认这不是断章取义）：

```css
…--cds-oncolor-200:#f8f8f7bf;--cds-oncolor-300:#f8f8f780;--cds-clay:#d97757;--cds-clay-emphasized:#c6613f;--cds-heather:#cbcadb;--cds-plum:#827db…
```

**注意三份来源给出三个不同值**：

| 来源 | 值 |
| :--- | :--- |
| v2 文档（v2.37337.1） | `#cc5a36`（双模同值） |
| open-claude-ui 分支实现 | `var(--cds-clay-hover)` → light `#cc5a36` / dark `#e08264` |
| **3.6556.2 实测** | **`#c6613f`** |

### 1.3.2 无需修改的令牌（已验证一致） [#132-无需修改的令牌已验证一致]

35 阶 gray 与 35 阶 orange **全部对齐**，仅 1 处写法差异（值等价）：

| 令牌 | ours | 3.6556.2 | 判定 |
| :--- | :--- | :--- | :--- |
| `--cds-gray-870` | `#111111` | `#111` | ✅ 值等价，仅书写长度不同 |

**证据**：

```bash
# gray: ours=35 cli=35 diff=1   (唯一差异 gray-870: #111111 vs #111)
# orange: ours=35 cli=35 diff=0
```

完整 35 阶表见 [4.3](/docs/v4/04)。

### 1.3.3 缺失的动效与结构 [#133-缺失的动效与结构]

| 类别 | ours | 3.6556.2 | 交集 | 缺失 | 我方独有 |
| :--- | ---: | ---: | ---: | ---: | ---: |
| `@keyframes cds-*` | 32 | **55** | 11 | **44** | 21 |
| `data-cds` 命名空间 | 22 | **45** | 18 | **27** | 4 |
| `@property --cds-*` | 19 | **24** | 17 | **7** | 2 |

**证据**：

```bash
# keyframes
comm -12 / -13 / -23 对 ours(32) 与 client(55) 做集合运算 → 11 / 44 / 21
32 = 11 + 21  ✓     55 = 11 + 44  ✓

# data-cds
comm 对 ours(22) 与 client(45) → 18 / 27 / 4
22 = 18 + 4   ✓     45 = 18 + 27  ✓

# @property
comm 对 ours(19) 与 client(24) → 17 / 7 / 2
19 = 17 + 2   ✓     24 = 17 + 7   ✓
```

具体清单见 [第五章](/docs/v4/05)。

### 1.3.4 结构性变更（需要改代码，不只是改值） [#134-结构性变更需要改代码不只是改值]

| 变更 | 影响 |
| :--- | :--- |
| 骨架屏从 `.skeleton-shimmer::after` 改为 **双层 `data-cds` 组件 + `.cds-skel-sweep-band` 子元素** | 组件标记需重写 |
| 新增 `data-hold` 三态揭示时序 | 需新增可选的揭示延迟控制 |
| 暗色从 `.dark` class 改为 **`[data-mode=dark\|light\|system]`** | 暗色切换逻辑需重写 |
| RTL 从简单 255° 翻转改为 **`:lang(...)` 精确语言列表 + `animation-direction:reverse`** | RTL 选择器需重写 |

详细证据见 [第三章](/docs/v4/03)。

---

## 本章证据索引 [#本章证据索引]

| 断言 | 证据来源 |
| :--- | :--- |
| 版本 `3.6556.2` | ASAR 内 `package.json`；`Info.plist` |
| ASAR 根摘要 | `shasum -a 256` 与 REA `artifacts[0].digest.sha256` 双向一致 |
| 572/546/7/0/6621556 | REA `records[0].normalized_result.statistics` |
| 629 个 ASAR 条目 | 直接解析 ASAR header 计数 |
| 7 个 renderer 入口 | ASAR `.vite/renderer/` 目录列表 |
| 532 文件截断 / 1064 条 limitation | REA `records[0].normalized_result.limitations` |
| 12 个语义族全 partial | REA `semantic_graph.coverage.families` |
| `clay-emphasized = #c6613f` | `grep` 主样式表：2 处定义（`:root` / `.cds-root`），值一致，0 处暗色覆盖 |
| gray/orange 35 阶对齐 | 逐阶对比 ours vs cli |
| 55/45/24 vs 32/23/19 | 三方 `sort -u \| wc -l` |
