---
description: Ailoha iOS 前端三档重构方案、推荐路径、迁移波次与人工确认点
status: request_changes
updated: 2026-08-12
sources:
  - repo://ailoha-agent-iOS@5e6ac6e41c53780c85808c92290d2bd38f809123
confidence: high
sensitivity: internal
---

# 重构方案与迁移策略

## 建议结论

选择 **B：演进式垂直切片**。先建立账户、日志、测试三条保护边界，再以 TaskRepository 统一 Home/Chat/Task 详情；随后迁移 Contact、Calendar 和系统扩展合同。它保留现有产品能力与回滚通道，也能逐步删除旧路径。不要先做全量 MVVM 重命名，也不要一次性把 656 个生产 Swift 文件搬进新目录。

## 当前执行状态

Wave 0 在隔离 worktree 形成 hosted substrate 与 account/effect remediation。Exact `45ba8781…e44c` 的独立 verdict 为 `request_changes`（0 P0 + 1 P1）；Calendar logout/reset P1 已关闭，但 credential Logger regex inventory 仍有括号 typealias、`Optional.some` 与 typed closure receiver 等同根邻接绕过。65/65 + 129/129 全绿仍不能授权 Wave 1。后续应优先以 SwiftSyntax/AST 收敛 source→known-sink，或明确有限、版本化的 syntax contract，不继续把枚举正则外推成完整语言级 taint。

## 三档方案

| 方案 | 做什么 | 优点 | 主要代价 / 风险 | 适用条件 |
|---|---|---|---|---|
| A 保守护栏 | 修 P0、补 hosted tests、修 scheme；维持现有 owner 与 locator | 交付快、行为变化小 | 状态/导航双重真相继续累积；后续 feature 成本仍高 | 只能投入 1–2 个短周期，且随后明确转入 B |
| **B 演进式垂直切片（推荐）** | Strangler：新协议/AccountScope 与旧实现并存；Task→Contact→Calendar 逐域迁移；每域有 adapter、指标、删除门槛 | 风险与学习平衡；可逐步证明目标边界 | 迁移期短暂双路径，需要纪律和清晰 owner | 能稳定投入多个迭代，并接受先做 guardrail |
| C 目标架构重写 | 新 AppShell/Feature Stores/transport/design system 后切流 | 目标模型最整洁 | 长分支、设计与行为漂移、迁移和回归面最大；难验证隐性 App Group/ARPC 合同 | 只有可冻结产品、完整行为基线、专职迁移团队与明确回滚时 |

## 目标不变量

架构形态可以调整，但以下合同不能退让：

1. 一个账户作用域内，每类 canonical entity 只有一个 owner；UI 可以有多个 query projection。
2. logout / account switch 会取消任务、清内存/磁盘/App Group account state，再销毁 scope。
3. UI 不直接依赖 generated API、WebSocket 或全局 service；effect 通过 typed protocol 注入。
4. cid/temp/server ID 收敛幂等；重复、乱序和重连事件不会创建第二真相。
5. 路由是 typed state + effect，不依赖固定时间 sleep 判断页面是否已经出现。
6. 跨进程 payload 有 version、account、environment、expiry 与恢复策略。
7. 设计 token、可缩放排版、Reduce Motion 和原生语义控件是组件合同，不靠页面补丁。
8. 每条旧路径都有 successor、rollout 信号、删除阈值和回滚方式。

## Wave 0 — 保护用户与建立可测试性

**2026-08-12 overlay：exact `45ba8781…e44c` implementation verdict 为 `request_changes`（0 P0 + 1 P1）；docs/page approve。** 历史反例、当前回应、证据边界与复审条件见 [Wave 0 Implementation Overlay](wave0-implementation.md)。下列条目是交付合同，不是集成完成声明。

**直接交付**

- `AccountScope.reset()` 第一版：统一枚举 Contact、Calendar、Task、附件、Live Activity、导入与运行任务。
- credential logging policy：禁止值/前缀进入 ALHLogger/OSLog；精确 redaction tests。
- Hosted app test target；修复 dangling scheme。
- A→logout→B、Calendar published state、token log 三组回归测试。

**用户/生产结果**：账户切换第一帧不暴露旧数据，日志不含可关联 credential 片段。

**人工确认点**：哪些本地状态属于账户、设备或环境；清理失败时强制登出还是阻止切换。

**回滚 / recovery**：账户清理必须 fail-closed。reset 由单一 coordinator 调用，并暂时保留旧 clear 方法作为完整清理 adapter；新实现异常时只能回退到仍执行全部清理的安全实现，或阻止账号切换并要求重新认证，绝不能关闭 orchestrator 后继续进入新账户。安全日志改动不回滚。

## Wave 1 — 明确组合根、账户作用域与导航 effect

```text
AilohaApp / RootPage
  → AppShell(state, dependencies)
      → unauthenticated dependencies
      → AccountSessionScope(accountId, environment)
      → NavigationStore
```

- 引入 typed `AppDependencies`，先包住现有 singleton，不要求立即重写服务。
- `AccountSessionScope` 构造 account-owned repositories，并拥有 cancellation bag。
- 把 Task deep link 转成 `NavigationIntent`：resolve → deduplicate → commit route；为 replace stack 和同任务重入写 reducer tests。
- 新功能禁止新增 `ServiceLocator.resolve`、裸 `.shared`、字符串 NotificationCenter 业务事件。

**删除门槛**：Task route 不再 sleep；visibleTaskChat self-heal 的生产信号为零且回归测试覆盖后删除补偿字段。

## Wave 2 — TaskRepository 试点

为什么先选 Task：它连接首要用户价值、Home/Chat、REST/ARPC、临时 ID、Widget/Live Activity，也最能证明目标架构是否可用。

```text
REST snapshot ─┐
ARPC event ────┼→ TaskRepository → canonical Task + transition log
local intent ──┘       ├→ HomeQuery
                       ├→ ChatQuery
                       └→ SystemSurfaceProjection
```

迁移顺序：

1. 写现状 golden tests：create、cid→server ID、processing、feedback、complete、cancel、重连重复消息。
2. 在旧 `TaskStateManager`/`HomeViewModel` 前增加 repository adapter，双读对比但只单写。
3. 先迁 Home read projection，再迁 Chat read projection，最后迁 mutation/effect。
4. Chat V2 建观测：首内容、滚动 hitch、重复/丢消息、crash、route failure；分级 rollout。
5. 达到等价和稳定阈值后删除 Home 独立 merge、TaskState adapter、Chat V1 与相关 flag。

**人工确认点**：乐观更新失败的用户语义；Chat V2 指标阈值；V1 删除日期。

## Wave 3 — Contact 与 Calendar 领域化

### Contact

- canonical `ContactRepository`：实体、version、REST/ARPC 幂等。
- `ContactListQuery`：分页/搜索/排序；`ContactDetailQuery`：tasks/events；`MergeSession`：临时编辑状态。
- Contact detail 按 header、history、editor 拆窄 observation model；以 SwiftUI trace 验证，不以文件数验收。

### Calendar

- canonical `CalendarEventRepository` + range query cache；EventKit 仍是后端权威的 mirror effect。
- month/day grouping 变成 keyed projection，只重算受影响日期。
- editor/selection 是 screen session，不进入 repository。
- Calendar reset test 确保 published projection 与 cache 一起清除。

**回滚**：新 repository 通过 adapter 输出旧模型；每个 surface 可单独切回旧 query，不双写服务端 mutation。

## Wave 4 — Design、可访问性与系统表面

- 设计 owner 确认 semantic color/type roles；一份 manifest 生成 Swift token 与 Figma mapping。
- Lora/Manrope 改为相对 text style；组件矩阵覆盖 AX1–AX5、中文/英文、窄屏。
- 原生 Button/Picker 优先；Calendar drag 增 accessibility actions 和表单替代路径。
- Onboarding 视频和动效读取 Reduce Motion；自动循环提供静态 fallback。
- CrossProcessEnvelope 版本化；App/Widget/Intent 先兼容读旧版、只写新版，统计旧 key 消失后删除。

## Wave 5 — 删除旧控制面

只有满足以下证据才删除：

- 迁移 surface 在目标 rollout 窗口内达到指标；无 unresolved P0/P1。
- adapter parity/golden tests 通过；rollback 仍在发布窗口内可用。
- `ServiceLocator` 注册、旧 singleton、NotificationCenter event、UserDefaults key、Chat V1、旧 token 和旧 App Group schema 均有明确 consumer=0 证据。
- 飞书/Figma surface tuple 指向当前 successor 与 commit，Reviewer 独立复核。

## 验证矩阵

| 维度 | 必测场景 | 证据 |
|---|---|---|
| Account | A→logout→B、token refresh 中切换、后台恢复、删除账号 | hosted test + first-frame screenshot + state dump |
| Task | create/alias、乱序/重复 ARPC、乐观失败、重连、Home/Chat 一致 | repository golden tests + integration tests |
| Navigation | 同 task、不同 task、replace stack、cold/warm deep link | reducer tests + UI tests，无固定 sleep |
| Cross-process | 旧/新 schema、过期、错 account/env、重复 intent | App/Widget contract fixtures |
| Design/A11y | AX1–AX5、Reduce Motion、VoiceOver action、窄屏/中英 | screenshot + accessibility audit |
| Performance | Contact detail 编辑、Calendar 大数据、Chat 长会话、大图导入 | SwiftUI Instrument / Time Profiler / Hangs/Hitches before-after |
| Rollout | flag fetch failure、environment switch、kill switch、旧路径删除 | telemetry dashboard + release checklist |

## 能力增量

本轮适合沉淀的是“可再生 iOS 架构快照 + claim ledger + migration gate”，而不是立即建设全自动重构 agent。只有当至少两个 feature 迁移都重复使用同一输入、验证和权限边界后，再升级为 CI：

```text
signal: account contract / dangling scheme / token log / forbidden new global dependency
cadence: PR
threshold: 任何新增命中或合同测试失败
action: 阻断并生成 evidence
owner: iOS Task Chief
human gate: schema migration、feature deletion、rollout
recovery: revert feature adapter / disable rollout，保留 evidence
```
