---
description: Ailoha iOS current main 的 L0–L4 递归架构、真实状态所有权、验证边界与重构切片
status: request_changes
updated: 2026-08-28
sources:
  - repo://ailoha-agent-iOS@6922f359ad08da70242e4ec0c5c4a1486bc2908d
  - https://github.com/Ailoha-ai/ailoha-agent-iOS/runs/98446822931
  - brain://reports/ios-frontend-refactor-map/current-main-architecture.architecture.json
  - brain://reports/ios-frontend-refactor-map/current-main-architecture.html
confidence: high
sensitivity: internal
---

# Ailoha iOS current main：从用户入口递归到状态与恢复

<!-- brain-capture:ios-frontend-current-main-recursive-architecture -->

## 一句话结论

当前 `main@6922f359` 已经有一条能工作的现代化脊柱：SwiftUI App / Root / typed Router、Chat V2、12 个本地 Package、App Group 恢复链、74 个通过的 Package 测试和大量静态 guard。真正阻碍整体重构的不是“没有分层”，而是**分层只完成到局部 seam，账号、canonical state、导航、跨进程恢复和 App 级验证仍由多个 owner 共同拼出来**。

这意味着下一步不该再按“大文件拆小”或“继续加 Package”衡量进展。最小而正确的重构颗粒，是一次只恢复一个可观察不变量，并让它在 App 生命周期里有自动裁判。

## 先说明这份文档能证明什么

- `fact`：来自 2026-08-28 获取的独立、干净、只读快照；revision 固定为 `6922f359ad08da70242e4ec0c5c4a1486bc2908d`。
- `fact`：远端 `main` 仍指向这个 SHA；最新提交时间为 2026-08-27T15:36:04+08:00。
- `fact`：Archify 图的 34 个源码引用均在该快照解析成功，showcase 结构检查 9/9 通过。
- `fact`：该 SHA 的 Xcode Cloud `ailoha-assistant | Default | Archive - iOS` 成功。
- `fact`：同 revision 的后续[首启与登录前运行基线](current-main-runtime-baseline-2026-08-28.md)已在全新 iOS 26.5 Simulator 上完成 clean build、首启、登录页、Light appearance、最大 Dynamic Type 与 shared scheme test 入口验证。
- `boundary`：运行基线停在未登录表面；没有运行真账号、生产 API、真实 APNs / ActivityKit、VoiceOver、Reduce Motion、ETTrace、memgraph 或真机 Always-On。静态结构、Package 绿测和登录前截图都不能证明生产行为。
- `boundary`：这份文档描述 current main，不代表 current Release，更不代表线上版本。

## 可探索图

- [打开 current main 完整架构图](current-main-architecture.html)
- [查看冻结的 Archify specification](current-main-architecture.architecture.json)
- [查看 current main 首启与登录前运行基线](current-main-runtime-baseline-2026-08-28.md)

图里只画 current fact。目标架构、建议 owner 和未来数据流放在本文后半段，不混进当前图。

## L0：用户面对的不是页面集合，而是一条连续循环

从代码能够确认的主循环是：

`启动 / 系统唤起 → 登录或恢复身份 → Home / Onboarding → 创建或进入 Task → Chat / Widget / Contact / Calendar 形成结果 → 页面与系统表面同步 → 下次启动继续恢复`

用户并不关心数据来自 REST、ARPC 还是 App Group。用户只会感知四件事：

1. 现在是不是我的账号和我的上下文；
2. 我刚做的动作有没有被记住；
3. App、通知和灵动岛是不是在说同一件事；
4. 失败后重进，事情会继续、回滚，还是悄悄丢失。

因此最上层架构不变量不是“MVVM 是否纯”，而是：**同一个用户意图在所有表面只能产生一个权威结果，旧账号和旧 session 不能继续落地副作用。**

## L1：四个 Xcode 产品共同组成客户端

| 产品 | 当前职责 | 真相边界 |
|---|---|---|
| `Ailoha.app` | App 生命周期、登录分流、页面树、feature orchestration、REST / ARPC、系统权限和恢复 | 持有大多数跨 feature 决策，也承受最多隐式耦合 |
| `AilohaShared.framework` | App / Widget / AppIntent / Notification 可共同使用的 token、App Group、payload、pending action、Live Activity end 等合同 | 跨进程可复用，不等于拥有账号 session 的最终裁决 |
| `AilohaWidgetExtension` | Widget、Live Activity UI、AppIntent 动作、extension 侧网络与交接 | 进程可被系统随时回收，不能依赖主 App 内存 |
| `AilohaNotificationContent` | 富通知展示与交互动作 | 独立 extension 生命周期，必须通过稳定合同恢复 |

`fact`：工程没有 App unit-test 或 UI-test product；共享 scheme 的 TestAction 仍引用不存在的 `ailoha-assistant-sharedTests.xctest`。因此“四个产品能一起 build / archive”与“四个产品的行为合同被测试”是两件不同的事。

## L2：主 App 的真实运行脊柱

### 1. 进程初始化

`AilohaApp.init()` 按顺序接线日志、字体、ShareKit、Sentry、事件追踪、环境、图片流水线和 pre-login services；`AppDelegate` 接远程通知、通知 category、device registration 与 Live Activity token 观察。

这个入口已经承担 composition root 的角色，但它组合的是大量 `.shared` 和 `ServiceLocator`，不是完整 typed dependency graph。

### 2. 登录分流

`SplashGate → RootPage`。`RootPage` 根据 `AuthService.isAuthenticated && hasCompletedOnboarding` 在 `OnboardingPage` 与 `MainTabPage` 之间切换。

`RootPage` 自己拥有：

- `NavigationUIState`
- `SidebarViewModel`
- `VersionUpdateCoordinator`
- 账号级 `MailboxScanStore`
- `FirstEncounterGuideState`

这是 current main 的积极变化：邮箱扫描与首次引导没有继续做成进程级 singleton，而是由 Root 创建、按 account ID activate，再注入页面树。

### 3. 登录后的主壳

`MainTabPage` 用 `ManagedNavigationStack` 持有路由栈；顶层 tab 通过 `NavigationUIState.currentRoute` 切换 Home、Contact、Calendar、Discover，子页面通过 typed `AppRoute` push。

Chat 在 main 只剩 `TaskChatPageV2`。旧 `TaskChatPage` 与 `ChatPageDebugFlags` 不在树中，所以“删除 Chat V1”不再是 main 的任务。

### 4. Feature 页面

- Onboarding / Home：首次体验、任务列表、搜索、输入和进口草稿。
- Task / Chat：Task 快照、Chat rows、输入附件、乐观反馈、ARPC topic 与恢复。
- Contact：列表、搜索、详情、联系人相关 Task / Event、2Meet cluster 与 merge。
- Calendar：事件窗口、月 / 日 / 年投影、缓存、编辑与系统日历能力。
- Import / Share / Settings：外部文件、分享卡、账号和系统能力配置。

页面并不直接构成单一数据层。它们通过 App ViewModel、singleton、`ServiceLocator`、Package 类型、REST façade、ARPC handler 和通知共同更新。

## L3：谁真正拥有状态

| 领域 | 当前 canonical / 长生命周期 owner | 页面 projection | 副作用 / 恢复 owner | 当前问题 |
|---|---|---|---|---|
| 身份 | `AuthService.shared`、Keychain、App Group auth token | Root / Home 订阅 `AuthService` | `AilohaApp.initializeAfterLogin / cleanupAfterLogout`、ServiceLocator | 没有统一 AccountScope；各 feature 自己决定是否 reset |
| 导航 | `NavigationUIState` + Navigator path + `ExternalTaskNavigationStore` | `RootPage` / `MainTabPage` | Notification、URL、Live Activity handoff | typed route 与 Notification / 固定延时并存 |
| Task | `TaskStateManager` + `TaskLifecycleCoordinator` | `HomeViewModel`、`TaskChatViewModel` 各有自己的列表 / rows / optimistic state | REST、ARPC、App Group intent reconcile | canonical entity 与 Home query/merge 仍交叉拥有 |
| Contact | `ContactManager.shared` 同时持列表、搜索、cache、cluster、详情数据 | List / Detail 各有 ViewModel | REST + ARPC Contact handler | query generation 已有；账号 session fence 没有 |
| Calendar | `CalendarViewModel.shared` 同时持事件、派生日期索引、窗口 cache 和页面状态 | Calendar views 直接观察 shared VM | REST、EventKit / 外部日历 adapter | clearCache 不清 published projection；全量派生更新 |
| Onboarding | `OnboardingCoordinator` + Package reducer + Root-owned first encounter/mailbox state | OnboardingFeature / Home overlays | Auth、Google、权限、Shortcuts | reducer seam 真实；运行旅程和设计 lifecycle 仍不完整 |
| Import | `ImportInboxCoordinator` actor + `ImportFlowController.shared` | Root sheets / Home composer | App Group durable inbox、上传、恢复 | durable store 已抽出；账号 / 环境绑定仍由 App 提供 |
| Live Activity | `DeviceRegistrationService`、`LiveActivityEnder`、`SharedConstants`、Widget Intent | Activity UI / Lock Screen / Main App | ActivityKit、APNs、App Group pending ledgers | 多个真实 Activity 与 scalar token / observer 所有权需系统 replay |
| 日志 | `AilohaLoggingKit` + App logger / periodic uploader | Debug surfaces | file IO、rotation、quiesce、upload | 包边界成立；caller 仍可在脱敏前写 credential 前缀 |

这里的 owner 指“创建并维护状态，或负责不可重复副作用和恢复”，不是文件所在目录。

## L4：六条需要能被团队复述的机制

### A. 账号切换

当前链路：

`AuthService.logout 清身份 → isAuthenticated 发布变化 → AilohaApp cleanup → Task / Import / Live Activity / ARPC 清理`

缺口：Contact 和 Calendar 没进入同一个同步 reset。`ContactManager` 的 generation 能阻止同一列表语境的旧请求覆盖新请求，但它不是 account/session token；logout 也没有建立一个新的 Contact generation。Calendar 的 `clearCache()` 只清内部 cache，不清 `events / eventsByDate`。

这就是 `PRIV-001 / PRIV-002` 的当前根因，不是“某个页面忘记刷新”。

### B. 外部任务导航

正向进展：URL 和 Live Activity 请求可先进入 `ExternalTaskNavigationStore`，并绑定 user / environment 后由主壳 claim / acknowledge，Splash 未挂载时不再天然丢失。

剩余缺口：普通 `.navigateToTask` Notification 与可恢复请求在 `MainTabPage` 汇合时，仍先看 `visibleTaskChatId`、sleep 100ms、再 pop / push。这个固定延时是生命周期竞争的补偿，不是确定性路由规则。

### C. Task 状态与 Chat 投影

正向进展：Task publisher 会去重；不可见页面主动释放订阅；Chat V2 使用 diffable collection view，长 reply 布局 guard 通过。

剩余缺口：每次真实 `TaskData` 变化仍会完整执行 `ChatRowItem.buildRows`。diffable data source 能减少 cell 更新，不会自动消除 projection 的全量构建成本。Home 还独立维护分页、REST merge、placeholder reconcile 和 optimistic removal。

### D. 跨进程恢复

正向进展：App Group 有 durable inbox、pending action、pending navigation、pending Live Activity end 等账本；当前 lifecycle 静态 guard 通过。

剩余缺口：这些账本不都携带同一套 `account × environment × session × operation` 信封，也没有真实 suspended extension / account rotate replay 证明旧工作不能在新身份下完成 network、EventKit 或文件写入。

### E. Package seam

12 个 Package 不是空目录。TaskCore、ImportCore、TwoMeetCore、SpeechKit、MarkdownKit、LoggingKit、OnboardingCore 等已经拥有可执行策略、缓存、store 或设备副作用。

剩余缺口：`GlobalImports.swift` 用 `@_exported import` 把 feature module 暴露给整个 App。调用文件看不到自己的直接模块依赖；身份、network、canonical state 与组合恢复也大多还在 App target。Package 数量不能当作 feature ownership 完成度。

### F. 验证体系

当前有三类证据：

1. 12 个 Package、19 个 test 文件，本轮实际执行 74/74 通过；
2. 65 个 `check_*.py`、31 个 `run_*tests/checkpoint` 脚本，本轮抽查 7 个结构 / 生命周期 guard 全部通过；
3. 28 个 Agent-led E2E case manifest。

缺口是 App 级裁判：主线没有 hosted App test target，scheme dangling，PR 默认只跑 lightweight，完整 Simulator build 需 PR 正文显式写 `[full-ios-build]`。Xcode Cloud Archive 成功证明可归档，不证明账号、导航、Widget 或恢复行为正确。

## 完整快照清点

| 表面 | Swift 文件 | Swift 行数 | 说明 |
|---|---:|---:|---|
| `Ailoha` App target source tree | 350 | 98,552 | 页面、服务、ARPC、组件与工具 |
| `AilohaShared` | 22 | 7,000 | 跨进程合同与恢复实现 |
| `AilohaWidget` | 6 | 2,703 | Widget / Live Activity / Intent |
| `AilohaNotificationContent` | 1 | 605 | 富通知 extension |
| `Packages`（含 Package tests） | 341 | 37,673 | 12 个本地 Package |
| 仓库总计 | 771 | 163,172 | 还包含 scripts 中的 Swift harness |

辅助信号：35 个 `@StateObject`、44 个 `@ObservedObject`、19 个 `@EnvironmentObject`、222 个 `@Published`、52 个 `static let shared`、80 个 `NotificationCenter.default`、50 个 `UserDefaults.standard`。这些是查找入口，不是 302 个缺陷。

当前高责任浓度文件包括 `ChatCollectionView` 1960 行、`TaskHistoryService` 1912 行、`ScreenshotTaskLiveActivity` 1851 行、`ContactManager` 1786 行、`DeviceRegistrationService` 1568 行、`HomeViewModel` 1516 行、`ContactDetailViewModel` 1438 行。行数本身不构成问题；只有当一个切片跨越多个 authority、失败语义或恢复边界时才值得拆。

## current main 已经做对的地方

1. Chat V2 已成为 main 唯一路由，不再有双轨结构债。
2. `AppRoute` 是 typed enum，页面出口与 screen tracking 有集中入口。
3. Root-owned mailbox / first encounter 展示了“状态归页面树 owner，而不是继续加 singleton”的可迁移模式。
4. `ExternalTaskNavigationStore` 已把易丢的一次性事件升级为可 claim / acknowledge 的持久请求。
5. 多个 Package 已拥有真实 policy / store / effect，74 个测试不是装饰。
6. Design Token 已有 DTCG manifest → generated Swift 的确定性链，本轮 `--check` 通过。
7. App Group recovery、Live Activity end、Import inbox 等已经有明确的 durable ledger 方向。
8. 当前 head 的 Xcode Cloud Archive 成功，说明打包链不是完全失控。

重构应复用这些支点，不应该为了“更纯”把它们推倒重来。

## 旧问题在完整 current main 上如何重判

| 结论 | current main 状态 | 解释 |
|---|---|---|
| Chat 双轨 | **结构关闭** | V1 / flag consumer 为零；剩余是 V2 runtime 与进入 Release 的 gate |
| Package 不存在 / 不可测 | **旧结论失效** | 12 个 Package、74/74 tests；问题改为 owner 和组合合同 |
| 颜色完全无共同来源 | **部分失效** | generated token 链已成立；`ALHColors` 手写 adaptive source 仍并存 |
| 账号切换隔离 | **仍成立，P0** | Task / Import / Live Activity 已清；Contact / Calendar 与共同 late-work fence 未闭合 |
| credential 前缀日志 | **仍成立，P0** | APNs、Soniox、screenshot update token 的前缀仍在 current source |
| 跨进程旧工作 | **仍成立，P0** | durable ledger 增多，但共同 session envelope 与真实 system replay 仍缺 |
| App 级测试缺口 | **仍成立，P1** | Package / scripts 丰富，不等于 App target 行为测试 |
| fixed-delay 导航 | **仍成立，P1** | 100ms sleep 仍参与 route 去重 / push |
| Dynamic Type | **仍成立，P1** | Lora / Manrope 入口使用 `fixedSize`；没有系统缩放合同 |
| Reduce Motion | **部分改善、仍 open** | main 有 2 个读取点；active Onboarding 视频和 repeatForever 未覆盖 |
| Calendar 派生性能 | **代码风险成立，生产影响未知** | 每次 events 写入全量分组 / 排序 / 再发布，查询还新建 formatter |
| Contact 详情 observation | **页面 fan-out 已复现，生产影响未知** | 12 次姓名输入稳定触发 12 次 Notes body、全量解析与日期分组；1k / 5k Debug 每次无关投影约 23.6 / 91.5ms |
| 多图内存峰值 | **代码风险成立，生产影响未知** | InputPanel / Camera 先加载完整 Data 并解码 UIImage，后续缩略图不能消除首次峰值 |

## 最合适的工程认知颗粒

下面每一条都小到可以独立理解、实现、验证和回滚，但又足以恢复一个真实不变量。

### P0-01｜账号切换的第一帧

- **上下文**：用户 A 登出，用户 B 登录；Contact / Calendar 页面尚未发完新请求。
- **现在的问题**：Task 已 reset，Contact / Calendar published projection 没有在同一个 account transition 中同步归零。
- **怎么改**：先定义 `AccountTransition` / session generation；身份释放前让各 account-scoped owner 同步 reset，异步结果提交前校验同一 generation。
- **为什么**：页面 `onAppear` 清理只修表象；共同 transition 才能同时挡住第一帧和迟到回包。
- **验收**：A→logout→B；B 第一帧无 A 数据；释放 A 的 suspended response 后仍无 A 数据；Task / Contact / Calendar / Import 至少各一个 spy；重复 logout 幂等。

### P0-02｜旧 extension 工作不能借新账号落地

- **上下文**：Widget / Live Activity / Share extension 已保存动作，主 App 或账号随后切换。
- **现在的问题**：不同 ledger 的身份字段与 write fence 不统一。
- **怎么改**：所有不可逆动作携带 versioned `account + environment + session + operation` envelope；网络、EventKit、file writer 在真正写入前再验一次。
- **为什么**：只在入队时验证挡不住 suspended work 在 rotate 后继续。
- **验收**：暂停旧网络 / EventKit / writer，rotate session，再释放；三个 spy 都拒绝旧工作；新 session 同动作成功；unknown outcome 不自动重发。

### P0-03｜日志从源头不含 credential 值

- **上下文**：APNs、STT、Live Activity token 需要诊断，但日志会持久化 / 上传。
- **现在的问题**：caller 先把前缀拼进字符串，redactor 无法可靠知道它是 credential。
- **怎么改**：消息只记录 `present / length / hash-versioned-id` 等非值元信息；source→sink guard 和真实日志样本共同验证。
- **为什么**：继续增强 regex 永远追不上新字符串语法；值不进入消息才是稳定不变量。
- **验收**：三个 current caller consumer=0；日志文件、周期 segment、Sentry / OSLog 样本无值和前缀；guard 能被反例自测击中。

### P1-01｜App 行为测试先落一个最小宿主

- **上下文**：74 个 Package tests 都绿，但 P0 横跨 App、extension 与账号生命周期。
- **现在的问题**：Xcode project 没有真实 App test product，scheme 指向 ghost target。
- **怎么改**：只落一个 hosted test target，先接账号 transition、external navigation、一个 App Group recovery；不要一开始追求全 UI 自动化。
- **为什么**：它给后续重构提供组合裁判，也能删除 dangling scheme。
- **验收**：`xcodebuild test` 能运行真实 product；CI 默认执行；失败能阻止合并；fixture 不访问真实用户数据；target 可在一分钟级完成核心 suite。

### P1-02｜导航 effect 不再靠 100ms

- **上下文**：Push、URL、Live Activity、通知都可能在不同页面 / 栈状态进入同一 Task。
- **现在的问题**：固定 sleep 等 UI“稳定”，再读 visible id 和改栈。
- **怎么改**：把 `open task` 变成 typed effect，由一个 reducer 根据 current root、path、visible task、request id 原子决定 `no-op / push / replace`。
- **为什么**：确定性状态转换可以直接测试；时间等待无法表达正确规则。
- **验收**：冷启、未登录、Onboarding、Home、已有同 Task、另一个 Task、重复请求、newer request 八种表；零固定 sleep；每个请求最多一次 acknowledge。

### P1-03｜Calendar 单日变化只更新受影响日期

- **上下文**：编辑一个 occurrence 或收到一个增量事件。
- **现在的问题**：任意 `events` 赋值都会重扫全部事件、展开跨日 key、逐日排序，再发布整份 map；日期查询重复建 formatter。
- **怎么改**：先把日期 key 与 timezone formatter 变成稳定 owner；为 add / update / delete 计算 old-day / new-day delta；series / timezone / authoritative replacement 保留 full rebuild。
- **为什么**：不是所有变化都能增量化，显式区分 delta 与 rebuild 才不会牺牲正确性。
- **验收**：1k / 10k fixture；DST、all-day、跨日、series mutation 与时区切换结果等于全量 oracle；单 occurrence 只触达受影响 key；p95 与主线程预算达标。

### P1-04｜Contact 草稿与 Notes 投影各归自己的 owner

- **上下文**：用户停在 Notes tab，只输入一个姓名或电话字符，备注本身完全没变。
- **现在的问题**：editor draft 是 root VM 的 Published；Notes 又观察整个 VM。3×3 Debug 页面运行证明每次输入都会重做全部 Notes 投影；四个 child→root forwarding 是相邻放大器。
- **怎么改**：draft 归 `ContactFieldEditor` 本地持有，确认时 typed commit 一次；Notes 只接不可变 input/projection 与 action。consumer test 后再逐个删 child forwarding，canonical contact 仍只有一个 owner。
- **为什么**：先修已经实测的错误更新边界，不盲拆 36 个属性；名字输入时 Notes 投影应严格为 0。
- **验收**：20 次姓名/company 输入的 Notes body/projection 为 0；note 事务至多投影一次并与 full oracle 等价；同设备 Release trace、截图和视频绑定同 SHA。

### P1-05｜Chat rows 的增量投影

- **上下文**：一个 turn 内 processing、message、widget 会多次更新 TaskData。
- **现在的问题**：输入附件已有等价守卫，UI 也用 diffable data source，但每次真实 TaskData 变化仍全量 `buildRows`。
- **怎么改**：先用 signpost 区分 `TaskData → ChatRowItem` 与 collection apply / layout；只有 projection 超预算才引入 turn / message keyed delta。
- **为什么**：UI diff 和 projection diff 是两个成本层，不能凭代码形态提前重写。
- **验收**：20 / 100 / 500 turns，短文 / 长文 / 10 图；projection p95、diff apply、layout、峰值内存分开；row identity 与滚动锚点不回归。

### P1-06｜图片先降采样，再进入 UIImage

- **上下文**：相册 10 图或单张超大截图进入 Home / InputPanel。
- **现在的问题**：先 `loadTransferable(Data.self)` 和 `UIImage(data:)`，之后生成缩略图无法消除完整解码峰值。
- **怎么改**：用文件 / data provider + ImageIO thumbnail 在后台解码目标尺寸；原文件上传与 UI preview 分账。
- **为什么**：减少的是峰值 resident memory 和主线程解码，不只是最终图片尺寸。
- **验收**：1 / 10 张 12–48MP fixture；选择期间峰值内存、主线程 stall、取消后迟到 UI、图片方向与上传原文件一致性全部过门。

## 两级重构方案，不一次重写

### 方案 A｜保护现有结构

先不搬业务文件：

1. hosted App test target；
2. Account transition + session fence；
3. credential value-free logging；
4. P0 system replay。

优点是风险最小，能立刻保护现有 main。缺点是 ServiceLocator / singleton 和多 owner 仍在，只是被围住。

### 方案 B｜按垂直切片收 owner

在方案 A 的门禁上，选择 Task 或 Calendar：

1. typed dependencies 进入 feature composition；
2. canonical entity / query projection / effect recovery 分开；
3. Page 只观察窄 projection；
4. 旧 singleton / Notification / direct API consumer 有删除账本。

优点是每个切片能真正降低认知成本；缺点是没有方案 A 的组合测试时，重构很容易只改变文件位置。

不建议当前直接做“全 App 新架构重写”。当前 main 已有很多可复用 seam，且运行证据少于静态证据；一次性重写会同时丢掉真实恢复细节和回滚能力。

## 推荐执行顺序

1. **P0 verifier**：账号切换、credential source→sink、suspended extension rotate。
2. **P0 修复**：按 verifier 暴露的最小 owner / fence 缺口修，不先做全局 DI。
3. **P1 App test target**：让上述 verifier 进入默认 CI。
4. **P1 性能基线**：Calendar、Contact、Chat、10 图各一个固定 fixture + trace。
5. **P1 垂直切片**：优先 Task 或 Calendar，证明 typed owner 能替换旧入口。
6. **P1 设计系统门**：Dynamic Type、Reduce Motion、token / Figma revision。
7. **P2 freshness guard**：main SHA 变化时只标记受影响 claim，owner 复核后更新文档。

## 本轮验证收据

- Remote head：`main@6922f359ad08da70242e4ec0c5c4a1486bc2908d`。
- Snapshot：独立 shallow clone，初始 clean；未触碰用户当前 iOS 工作区。
- Package tests：12/12 packages，74/74 tests 通过。
- Static / lifecycle guards：modular package boundary、ARPC boundary、Logging boundary、external task navigation、Task Chat long reply、Calendar connection、Live Activity lifecycle 全部通过。
- Design tokens：`build.mjs --check` 通过。
- Xcode Cloud：该 SHA Archive success；不含 App 行为测试声明。
- Archify：34/34 source refs；showcase 9/9；0 errors；0 warnings。
- Visual review：桌面 light / dark 无节点、标签或线条遮挡；390px 内容无横向 overflow，但顶层 action toolbar 的 Theme / Style 左侧按钮被 viewport 裁切。核心图可读，移动端工具栏不满足完整交互验收，不能记为全量视觉通过。
- Runtime evidence：真账号、Simulator journey、ETTrace、memgraph、VoiceOver、APNs / ActivityKit replay 均未执行。

## 反证条件

以下任一事实出现，应更新本文，而不是把旧结论硬套到新 revision：

- main 新增真实 App test product，scheme / CI 默认执行并覆盖三条 P0；
- Contact / Calendar 接入共同 AccountScope，并有 A→B + late response 收据；
- credential caller 归零，真实所有 sink 样本值为空；
- external navigation 删除固定 sleep，reducer matrix 通过；
- performance trace 证明 Calendar / Contact / Chat / image path 未超预算；
- Release 吸收 main 的结构，或 main SHA 前进并移动上述锚点。

在这些条件发生前，这份 current-main 地图足以支撑“从哪里开始验证和重构”，但不授权声称整个前端已经理解完、已优化完或可以安全整体重写。
