docs(w2): mark plan tasks 1-7/9 done + sync CLAUDE.md §8 + write W2 retro
- plan: flip 43 checkboxes done across Task 1-7/9; Task 8 (manual speed baseline) and Task 10 (this retro) intentionally left open - CLAUDE.md §8: AI/ ⚠️ partial (AIRuntime/LLMSession/ModelStore/TokenChunk done, VLSession/Prompts/ pending); FileVault ✅; add Debug/DebugAIRunner ✅; drop bold from "W2 当前" and tag W2-W3 row 进行中 - new retros/2026-05-31-w2.md: status table, TBD speed baseline, off-plan Symptom/Timeline/ArchiveListView/AppIcon/Swift6 cleanup, Swift 6 + Simulator sandbox learnings, W3 prep checklist
This commit is contained in:
@@ -219,9 +219,10 @@ C2 解读 Tab 底部显示一段 diff 文本,**由 `ReportCompareService` 计算
|
|||||||
└── Me/ ❌ 只有 placeholder
|
└── Me/ ❌ 只有 placeholder
|
||||||
|
|
||||||
待建:
|
待建:
|
||||||
├── AI/ ❌ AIRuntime, LLMSession, VLSession, Prompts/
|
├── AI/ ⚠️ AIRuntime + LLMSession + ModelStore + TokenChunk ✅;VLSession + Prompts/ ❌
|
||||||
|
├── Debug/DebugAIRunner.swift ✅ DEBUG-only AI 自检入口
|
||||||
├── Services/ ❌ CaptureService, AskService, TrendService, ReportCompareService
|
├── Services/ ❌ CaptureService, AskService, TrendService, ReportCompareService
|
||||||
├── Persistence/FileVault.swift ❌ 原图加密目录管理
|
├── Persistence/FileVault.swift ✅ 原图加密目录管理
|
||||||
├── Security/AppLock.swift ❌ Face ID 启动锁
|
├── Security/AppLock.swift ❌ Face ID 启动锁
|
||||||
├── Features/Ask/ ❌ AskSheet (RAG 问答 UI)
|
├── Features/Ask/ ❌ AskSheet (RAG 问答 UI)
|
||||||
├── Features/Archive/
|
├── Features/Archive/
|
||||||
@@ -265,8 +266,8 @@ C2 解读 Tab 底部显示一段 diff 文本,**由 `ReportCompareService` 计算
|
|||||||
|
|
||||||
| 周次 | 必交付 |
|
| 周次 | 必交付 |
|
||||||
|---|---|
|
|---|---|
|
||||||
| W1 末 / **W2 当前** | 项目结构、MLX 跑通 Qwen3-1.7B、首个 token 在设备吐出 |
|
| W1 末 / W2 当前 | 项目结构、MLX 跑通 Qwen3-1.7B、首个 token 在设备吐出 |
|
||||||
| W2-W3 | AIRuntime + LLMSession,文字日记 + 基础 RAG 问答(打字机效果) |
|
| W2-W3 | AIRuntime + LLMSession,文字日记 + 基础 RAG 问答(打字机效果)(W2 进行中) |
|
||||||
| W3-W4 | VLSession + 统一拍照流程(单项 + 整份)、Asset / FileVault |
|
| W3-W4 | VLSession + 统一拍照流程(单项 + 整份)、Asset / FileVault |
|
||||||
| W4 末 | **C1 ArchiveListView**(分类 chip + 年份分组,接 @Query) |
|
| W4 末 | **C1 ArchiveListView**(分类 chip + 年份分组,接 @Query) |
|
||||||
| W4-W5 | 趋势(Swift Charts + AI 解读)、**C2 ReportDetailView**(三 Tab + 重新解读) |
|
| W4-W5 | 趋势(Swift Charts + AI 解读)、**C2 ReportDetailView**(三 Tab + 重新解读) |
|
||||||
|
|||||||
@@ -47,13 +47,13 @@
|
|||||||
**Files:**
|
**Files:**
|
||||||
- Modify: `康康.xcodeproj/project.pbxproj`(通过 Xcode UI 修改,不要手编)
|
- Modify: `康康.xcodeproj/project.pbxproj`(通过 Xcode UI 修改,不要手编)
|
||||||
|
|
||||||
- [ ] **Step 1:打开 Xcode 项目**
|
- [x] **Step 1:打开 Xcode 项目**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
open /Users/xuhuayong/apps/康康/康康.xcodeproj
|
open /Users/xuhuayong/apps/康康/康康.xcodeproj
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2:加入 MLX Swift 依赖**
|
- [x] **Step 2:加入 MLX Swift 依赖**
|
||||||
|
|
||||||
在 Xcode → File → Add Package Dependencies → 输入 URL:
|
在 Xcode → File → Add Package Dependencies → 输入 URL:
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ https://github.com/ml-explore/mlx-swift
|
|||||||
- `MLXOptimizers`
|
- `MLXOptimizers`
|
||||||
- `MLXRandom`
|
- `MLXRandom`
|
||||||
|
|
||||||
- [ ] **Step 3:加入 mlx-swift-examples(含 LLM 工具)**
|
- [x] **Step 3:加入 mlx-swift-examples(含 LLM 工具)**
|
||||||
|
|
||||||
继续 Add Package Dependencies,URL:
|
继续 Add Package Dependencies,URL:
|
||||||
|
|
||||||
@@ -78,19 +78,19 @@ https://github.com/ml-explore/mlx-swift-examples
|
|||||||
|
|
||||||
勾选 `MLXLLM` 和 `MLXLMCommon` 加到 **康康** target。
|
勾选 `MLXLLM` 和 `MLXLMCommon` 加到 **康康** target。
|
||||||
|
|
||||||
- [ ] **Step 4:确认 Build Settings**
|
- [x] **Step 4:确认 Build Settings**
|
||||||
|
|
||||||
Xcode → 康康 target → Build Settings → 搜 "Swift Language Version" → 确认 Swift 5(MLX 不支持 Swift 6 严格并发)。
|
Xcode → 康康 target → Build Settings → 搜 "Swift Language Version" → 确认 Swift 5(MLX 不支持 Swift 6 严格并发)。
|
||||||
|
|
||||||
康康 target → General → Minimum Deployments → iOS 17.0(MLX 要求)。
|
康康 target → General → Minimum Deployments → iOS 17.0(MLX 要求)。
|
||||||
|
|
||||||
- [ ] **Step 5:Build 验证**
|
- [x] **Step 5:Build 验证**
|
||||||
|
|
||||||
Xcode 顶部选模拟器(任何一个 iPhone 15+),按 ⌘B。
|
Xcode 顶部选模拟器(任何一个 iPhone 15+),按 ⌘B。
|
||||||
|
|
||||||
Expected:Build Succeeded,无依赖错误。
|
Expected:Build Succeeded,无依赖错误。
|
||||||
|
|
||||||
- [ ] **Step 6:提交**
|
- [x] **Step 6:提交**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cd /Users/xuhuayong/apps/康康
|
cd /Users/xuhuayong/apps/康康
|
||||||
@@ -105,7 +105,7 @@ git commit -m "build: add MLX Swift SPM dependencies"
|
|||||||
**Files:**
|
**Files:**
|
||||||
- Modify: `康康/Models/Models.swift`(全文重写)
|
- Modify: `康康/Models/Models.swift`(全文重写)
|
||||||
|
|
||||||
- [ ] **Step 1:把 Models.swift 替换为新内容**
|
- [x] **Step 1:把 Models.swift 替换为新内容**
|
||||||
|
|
||||||
打开 `康康/Models/Models.swift`,**整文件替换**为:
|
打开 `康康/Models/Models.swift`,**整文件替换**为:
|
||||||
|
|
||||||
@@ -268,7 +268,7 @@ final class ChatTurn {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2:更新 KangkangApp.swift Schema**
|
- [x] **Step 2:更新 KangkangApp.swift Schema**
|
||||||
|
|
||||||
打开 `康康/App/KangkangApp.swift`,替换 Schema 数组:
|
打开 `康康/App/KangkangApp.swift`,替换 Schema 数组:
|
||||||
|
|
||||||
@@ -282,7 +282,7 @@ let schema = Schema([
|
|||||||
])
|
])
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 3:删模拟器沙盒(破坏性迁移)**
|
- [x] **Step 3:删模拟器沙盒(破坏性迁移)**
|
||||||
|
|
||||||
在 Mac 上:
|
在 Mac 上:
|
||||||
|
|
||||||
@@ -293,13 +293,13 @@ xcrun simctl erase all
|
|||||||
|
|
||||||
(也可以在 Simulator → Device → Erase All Content and Settings)
|
(也可以在 Simulator → Device → Erase All Content and Settings)
|
||||||
|
|
||||||
- [ ] **Step 4:Build & Run 验证**
|
- [x] **Step 4:Build & Run 验证**
|
||||||
|
|
||||||
Xcode ⌘R 运行到模拟器,App 启动不崩 = Schema OK。
|
Xcode ⌘R 运行到模拟器,App 启动不崩 = Schema OK。
|
||||||
|
|
||||||
Expected:App 启动到 RootView,无 fatalError。
|
Expected:App 启动到 RootView,无 fatalError。
|
||||||
|
|
||||||
- [ ] **Step 5:提交**
|
- [x] **Step 5:提交**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add 康康/Models/Models.swift 康康/App/KangkangApp.swift
|
git add 康康/Models/Models.swift 康康/App/KangkangApp.swift
|
||||||
@@ -314,7 +314,7 @@ git commit -m "feat(models): add Asset/ChatTurn, indicator-report relationship,
|
|||||||
- Create: `康康/Persistence/FileVault.swift`
|
- Create: `康康/Persistence/FileVault.swift`
|
||||||
- Test: `康康Tests/FileVaultTests.swift`
|
- Test: `康康Tests/FileVaultTests.swift`
|
||||||
|
|
||||||
- [ ] **Step 1:写失败的测试**
|
- [x] **Step 1:写失败的测试**
|
||||||
|
|
||||||
创建 `康康Tests/FileVaultTests.swift`:
|
创建 `康康Tests/FileVaultTests.swift`:
|
||||||
|
|
||||||
@@ -369,13 +369,13 @@ struct FileVaultTests {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2:运行测试,确认 fail**
|
- [x] **Step 2:运行测试,确认 fail**
|
||||||
|
|
||||||
Xcode ⌘U 跑测试(在模拟器上跑)。
|
Xcode ⌘U 跑测试(在模拟器上跑)。
|
||||||
|
|
||||||
Expected:`FileVaultTests` 编译错误 "Cannot find 'FileVault' in scope"。
|
Expected:`FileVaultTests` 编译错误 "Cannot find 'FileVault' in scope"。
|
||||||
|
|
||||||
- [ ] **Step 3:写最小 FileVault 实现**
|
- [x] **Step 3:写最小 FileVault 实现**
|
||||||
|
|
||||||
创建 `康康/Persistence/FileVault.swift`:
|
创建 `康康/Persistence/FileVault.swift`:
|
||||||
|
|
||||||
@@ -454,19 +454,19 @@ final class FileVault {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 4:把 FileVault.swift 加入 康康 target**
|
- [x] **Step 4:把 FileVault.swift 加入 康康 target**
|
||||||
|
|
||||||
Xcode 右键 `康康/` 目录 → New Group "Persistence" → 把 FileVault.swift 拖进去,确认 Target Membership 勾选 "康康"。
|
Xcode 右键 `康康/` 目录 → New Group "Persistence" → 把 FileVault.swift 拖进去,确认 Target Membership 勾选 "康康"。
|
||||||
|
|
||||||
把 FileVaultTests.swift 拖进 康康Tests target,确认 Target Membership 勾选 "康康Tests"。
|
把 FileVaultTests.swift 拖进 康康Tests target,确认 Target Membership 勾选 "康康Tests"。
|
||||||
|
|
||||||
- [ ] **Step 5:跑测试,确认全 pass**
|
- [x] **Step 5:跑测试,确认全 pass**
|
||||||
|
|
||||||
Xcode ⌘U。
|
Xcode ⌘U。
|
||||||
|
|
||||||
Expected:`writeAndReadJPEGRoundtrip` / `removeMakesFileGone` / `wipeRemovesAllFiles` 全绿。
|
Expected:`writeAndReadJPEGRoundtrip` / `removeMakesFileGone` / `wipeRemovesAllFiles` 全绿。
|
||||||
|
|
||||||
- [ ] **Step 6:提交**
|
- [x] **Step 6:提交**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add 康康/Persistence/FileVault.swift 康康Tests/FileVaultTests.swift 康康.xcodeproj
|
git add 康康/Persistence/FileVault.swift 康康Tests/FileVaultTests.swift 康康.xcodeproj
|
||||||
@@ -481,7 +481,7 @@ git commit -m "feat(persistence): add FileVault with complete file protection"
|
|||||||
- Create: `康康/AI/ModelStore.swift`
|
- Create: `康康/AI/ModelStore.swift`
|
||||||
- Test: `康康Tests/ModelStoreTests.swift`
|
- Test: `康康Tests/ModelStoreTests.swift`
|
||||||
|
|
||||||
- [ ] **Step 1:写失败的测试**
|
- [x] **Step 1:写失败的测试**
|
||||||
|
|
||||||
创建 `康康Tests/ModelStoreTests.swift`:
|
创建 `康康Tests/ModelStoreTests.swift`:
|
||||||
|
|
||||||
@@ -531,11 +531,11 @@ struct ModelStoreTests {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2:运行测试,确认 fail**
|
- [x] **Step 2:运行测试,确认 fail**
|
||||||
|
|
||||||
⌘U → expect `Cannot find 'ModelStore'`.
|
⌘U → expect `Cannot find 'ModelStore'`.
|
||||||
|
|
||||||
- [ ] **Step 3:写 ModelStore 实现**
|
- [x] **Step 3:写 ModelStore 实现**
|
||||||
|
|
||||||
创建 `康康/AI/ModelStore.swift`:
|
创建 `康康/AI/ModelStore.swift`:
|
||||||
|
|
||||||
@@ -619,18 +619,18 @@ final class ModelStore {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 4:Xcode 中把文件加入 target**
|
- [x] **Step 4:Xcode 中把文件加入 target**
|
||||||
|
|
||||||
右键 `康康/` → New Group "AI" → 拖入 ModelStore.swift,勾 "康康" target。
|
右键 `康康/` → New Group "AI" → 拖入 ModelStore.swift,勾 "康康" target。
|
||||||
ModelStoreTests.swift 拖入 康康Tests target。
|
ModelStoreTests.swift 拖入 康康Tests target。
|
||||||
|
|
||||||
- [ ] **Step 5:跑测试,全绿**
|
- [x] **Step 5:跑测试,全绿**
|
||||||
|
|
||||||
⌘U。
|
⌘U。
|
||||||
|
|
||||||
Expected:3 个测试全 pass。
|
Expected:3 个测试全 pass。
|
||||||
|
|
||||||
- [ ] **Step 6:提交**
|
- [x] **Step 6:提交**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add 康康/AI/ModelStore.swift 康康Tests/ModelStoreTests.swift 康康.xcodeproj
|
git add 康康/AI/ModelStore.swift 康康Tests/ModelStoreTests.swift 康康.xcodeproj
|
||||||
@@ -647,7 +647,7 @@ git commit -m "feat(ai): add ModelStore with path management and bundle seed"
|
|||||||
|
|
||||||
本任务**不接 MLX**,只搭骨架。Task 6 才接真模型。
|
本任务**不接 MLX**,只搭骨架。Task 6 才接真模型。
|
||||||
|
|
||||||
- [ ] **Step 1:创建 TokenChunk.swift**
|
- [x] **Step 1:创建 TokenChunk.swift**
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
import Foundation
|
import Foundation
|
||||||
@@ -658,7 +658,7 @@ struct TokenChunk: Sendable {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2:创建 AIRuntime.swift 骨架**
|
- [x] **Step 2:创建 AIRuntime.swift 骨架**
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
import Foundation
|
import Foundation
|
||||||
@@ -754,19 +754,19 @@ actor AIRuntime {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 3:确认 Build 失败原因合理**
|
- [x] **Step 3:确认 Build 失败原因合理**
|
||||||
|
|
||||||
⌘B → expect "Cannot find 'LLMSession' in scope"(Task 6 才会建)。
|
⌘B → expect "Cannot find 'LLMSession' in scope"(Task 6 才会建)。
|
||||||
|
|
||||||
这是预期。我们要让 Task 6 写完后 AIRuntime 直接能工作。
|
这是预期。我们要让 Task 6 写完后 AIRuntime 直接能工作。
|
||||||
|
|
||||||
- [ ] **Step 4:把文件加入 target**
|
- [x] **Step 4:把文件加入 target**
|
||||||
|
|
||||||
把 TokenChunk.swift 和 AIRuntime.swift 拖进 AI group,勾 "康康" target。
|
把 TokenChunk.swift 和 AIRuntime.swift 拖进 AI group,勾 "康康" target。
|
||||||
|
|
||||||
(此时 Build 还是失败,正常)
|
(此时 Build 还是失败,正常)
|
||||||
|
|
||||||
- [ ] **Step 5:暂不提交**
|
- [x] **Step 5:暂不提交**
|
||||||
|
|
||||||
等 Task 6 完成、Build 通过后一起提交。
|
等 Task 6 完成、Build 通过后一起提交。
|
||||||
|
|
||||||
@@ -785,7 +785,7 @@ actor AIRuntime {
|
|||||||
|
|
||||||
具体路径在 App 启动时打印,见 Step 5。
|
具体路径在 App 启动时打印,见 Step 5。
|
||||||
|
|
||||||
- [ ] **Step 1:在终端下载模型(脚本一次性)**
|
- [x] **Step 1:在终端下载模型(脚本一次性)**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir -p ~/tiji-models && cd ~/tiji-models
|
mkdir -p ~/tiji-models && cd ~/tiji-models
|
||||||
@@ -796,7 +796,7 @@ huggingface-cli download mlx-community/Qwen3-1.7B-MLX-4bit \
|
|||||||
|
|
||||||
Expected:目录里有 `config.json` / `model.safetensors` / `tokenizer.json` 等。
|
Expected:目录里有 `config.json` / `model.safetensors` / `tokenizer.json` 等。
|
||||||
|
|
||||||
- [ ] **Step 2:写 LLMSession 实现**
|
- [x] **Step 2:写 LLMSession 实现**
|
||||||
|
|
||||||
创建 `康康/AI/LLMSession.swift`:
|
创建 `康康/AI/LLMSession.swift`:
|
||||||
|
|
||||||
@@ -866,11 +866,11 @@ actor LLMSession {
|
|||||||
|
|
||||||
> **注**:`MLXLMCommon` 的具体 API 版本可能在 GenerateParameters/stream 处略有差异。如果 Step 4 编译报错,查看 mlx-swift-examples 仓库 `Libraries/MLXLLM` 的最新示例,以仓库示例为准小幅调整。
|
> **注**:`MLXLMCommon` 的具体 API 版本可能在 GenerateParameters/stream 处略有差异。如果 Step 4 编译报错,查看 mlx-swift-examples 仓库 `Libraries/MLXLLM` 的最新示例,以仓库示例为准小幅调整。
|
||||||
|
|
||||||
- [ ] **Step 3:把 LLMSession.swift 加入 康康 target**
|
- [x] **Step 3:把 LLMSession.swift 加入 康康 target**
|
||||||
|
|
||||||
拖入 AI group,确认 Target Membership。
|
拖入 AI group,确认 Target Membership。
|
||||||
|
|
||||||
- [ ] **Step 4:Build,期望成功**
|
- [x] **Step 4:Build,期望成功**
|
||||||
|
|
||||||
⌘B。
|
⌘B。
|
||||||
|
|
||||||
@@ -878,7 +878,7 @@ Expected:Build Succeeded。
|
|||||||
|
|
||||||
若 MLX API 签名不匹配,参考 https://github.com/ml-explore/mlx-swift-examples 中 `Libraries/MLXLLM` 的最新 LLM 示例修正。
|
若 MLX API 签名不匹配,参考 https://github.com/ml-explore/mlx-swift-examples 中 `Libraries/MLXLLM` 的最新 LLM 示例修正。
|
||||||
|
|
||||||
- [ ] **Step 5:在 KangkangApp 启动时打印沙盒路径(临时调试)**
|
- [x] **Step 5:在 KangkangApp 启动时打印沙盒路径(临时调试)**
|
||||||
|
|
||||||
打开 `康康/App/KangkangApp.swift`,在 `WindowGroup { RootView() }` 内加一个 `.onAppear`:
|
打开 `康康/App/KangkangApp.swift`,在 `WindowGroup { RootView() }` 内加一个 `.onAppear`:
|
||||||
|
|
||||||
@@ -901,7 +901,7 @@ Expected:Build Succeeded。
|
|||||||
📁 App Support: /Users/.../data/Containers/Data/Application/<UUID>/Library/Application Support
|
📁 App Support: /Users/.../data/Containers/Data/Application/<UUID>/Library/Application Support
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 6:把模型拷到沙盒**
|
- [x] **Step 6:把模型拷到沙盒**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
APP_SUPPORT="<上面控制台打印的路径>"
|
APP_SUPPORT="<上面控制台打印的路径>"
|
||||||
@@ -909,7 +909,7 @@ mkdir -p "$APP_SUPPORT/Models"
|
|||||||
cp -R ~/tiji-models/Qwen3-1.7B-MLX-4bit "$APP_SUPPORT/Models/"
|
cp -R ~/tiji-models/Qwen3-1.7B-MLX-4bit "$APP_SUPPORT/Models/"
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 7:提交(本任务 + Task 5 一起)**
|
- [x] **Step 7:提交(本任务 + Task 5 一起)**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add 康康/AI/ 康康/App/KangkangApp.swift 康康.xcodeproj
|
git add 康康/AI/ 康康/App/KangkangApp.swift 康康.xcodeproj
|
||||||
@@ -924,7 +924,7 @@ git commit -m "feat(ai): add AIRuntime actor and LLMSession with MLX Qwen3-1.7B"
|
|||||||
- Create: `康康/Debug/DebugAIRunner.swift`
|
- Create: `康康/Debug/DebugAIRunner.swift`
|
||||||
- Modify: `康康/Features/Me/MeView.swift`
|
- Modify: `康康/Features/Me/MeView.swift`
|
||||||
|
|
||||||
- [ ] **Step 1:创建 DebugAIRunner**
|
- [x] **Step 1:创建 DebugAIRunner**
|
||||||
|
|
||||||
`康康/Debug/DebugAIRunner.swift`:
|
`康康/Debug/DebugAIRunner.swift`:
|
||||||
|
|
||||||
@@ -998,7 +998,7 @@ struct DebugAIRunner: View {
|
|||||||
#endif
|
#endif
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2:在 MeView 末尾挂上(仅 DEBUG)**
|
- [x] **Step 2:在 MeView 末尾挂上(仅 DEBUG)**
|
||||||
|
|
||||||
打开 `康康/Features/Me/MeView.swift`,把现有内容整体替换为:
|
打开 `康康/Features/Me/MeView.swift`,把现有内容整体替换为:
|
||||||
|
|
||||||
@@ -1025,15 +1025,15 @@ struct MeView: View {
|
|||||||
#Preview { MeView() }
|
#Preview { MeView() }
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 3:在 Xcode 中加入文件**
|
- [x] **Step 3:在 Xcode 中加入文件**
|
||||||
|
|
||||||
右键 `康康/` → New Group "Debug" → 拖入 DebugAIRunner.swift,勾 "康康" target。
|
右键 `康康/` → New Group "Debug" → 拖入 DebugAIRunner.swift,勾 "康康" target。
|
||||||
|
|
||||||
- [ ] **Step 4:Build,确认 OK**
|
- [x] **Step 4:Build,确认 OK**
|
||||||
|
|
||||||
⌘B → Expected: Build Succeeded。
|
⌘B → Expected: Build Succeeded。
|
||||||
|
|
||||||
- [ ] **Step 5:提交**
|
- [x] **Step 5:提交**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add 康康/Debug/ 康康/Features/Me/MeView.swift 康康.xcodeproj
|
git add 康康/Debug/ 康康/Features/Me/MeView.swift 康康.xcodeproj
|
||||||
@@ -1094,7 +1094,7 @@ git commit --allow-empty -m "milestone: W2 LLM 自检通过 (simulator)"
|
|||||||
**Files:**
|
**Files:**
|
||||||
- Create: `康康Tests/ModelsSchemaTests.swift`
|
- Create: `康康Tests/ModelsSchemaTests.swift`
|
||||||
|
|
||||||
- [ ] **Step 1:写 schema 烟测**
|
- [x] **Step 1:写 schema 烟测**
|
||||||
|
|
||||||
```swift
|
```swift
|
||||||
import Testing
|
import Testing
|
||||||
@@ -1179,7 +1179,7 @@ struct ModelsSchemaTests {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] **Step 2:加入 康康Tests target,跑测试**
|
- [x] **Step 2:加入 康康Tests target,跑测试**
|
||||||
|
|
||||||
⌘U。
|
⌘U。
|
||||||
|
|
||||||
@@ -1187,7 +1187,7 @@ Expected:3 个测试全 pass。
|
|||||||
|
|
||||||
若 cascade 删除测试失败 → 检查 `Indicator.report` 反向关系是否声明正确(参考 Task 2)。
|
若 cascade 删除测试失败 → 检查 `Indicator.report` 反向关系是否声明正确(参考 Task 2)。
|
||||||
|
|
||||||
- [ ] **Step 3:提交**
|
- [x] **Step 3:提交**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
git add 康康Tests/ModelsSchemaTests.swift 康康.xcodeproj
|
git add 康康Tests/ModelsSchemaTests.swift 康康.xcodeproj
|
||||||
|
|||||||
42
docs/superpowers/retros/2026-05-31-w2.md
Normal file
42
docs/superpowers/retros/2026-05-31-w2.md
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
# W2 Retro · 2026-05-31
|
||||||
|
|
||||||
|
> 范围:2026-05-19(W2 起)→ 2026-05-25(W2 中段写,W3 周一前回看修订)。本次 retro 在 W2 中段写,主要是周末批量收尾的留痕。
|
||||||
|
|
||||||
|
## Status
|
||||||
|
|
||||||
|
| 风险/里程碑 | 状态 | 备注 |
|
||||||
|
|---|---|---|
|
||||||
|
| R1 · MLX 跑通 | ⚠️ 部分通过 | LLMSession.load 通过 Swift Testing 烟测,真实 tok/s 待用户手动 DebugAIRunner 验证 |
|
||||||
|
| R4 · Schema 迁移 | ✅ 通过 | 5 + 1(Symptom)个 @Model,3 + 2 个关系烟测全绿 |
|
||||||
|
| 本周里程碑 · AI 基座骨架 | ✅ | AIRuntime / LLMSession / ModelStore / FileVault 全部交付,build 干净 0 warning |
|
||||||
|
|
||||||
|
## 速度基线
|
||||||
|
- 模拟器(iPhone 17 Sim, Apple Silicon Mac):**TBD**(W3 周一前由 xuhuayong 在 macOS Designed for iPad 内点 DebugAIRunner 填入)
|
||||||
|
- 真机 iPhone 15+:**待 W3 验证**(本周未连真机,模型只 sideload 到 macOS sandbox)
|
||||||
|
|
||||||
|
> 验收门槛:模拟器 < 5 tok/s 触发 R1 红线(换 llama.cpp,W2 plan revert)。当前烟测路径无法测速,需 manual。
|
||||||
|
|
||||||
|
## 计划外完成
|
||||||
|
- **Symptom 模块**:新增 @Model + Start/End sheets + OngoingSymptomsCard。这是 CLAUDE.md §10 红线 #6 "新功能必须问'清单里有吗'" 的例外,由产品负责人决定加入。
|
||||||
|
- **Timeline 统一时间线**:TimelineEntry + TimelineRow + DateSection + TimelineGrouping,被 HomeView 和 ArchiveListView 共享。
|
||||||
|
- **ArchiveListView 提前打底**(原计划 W4):接 @Query 拉 Indicator/Report/Diary/Symptom,filter chips + 年/月分组 + 空态。
|
||||||
|
- **AppIcon**:Light/Dark/Tinted 三套 9 sizes + SVG 源。
|
||||||
|
- **Swift 6 并发清扫**:`SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor` 下,把 ModelStore / FileVault / ModelKind 显式标 nonisolated,LLMSession 用 task-scoped Device.withDefaultDevice 替代 deprecated API。
|
||||||
|
|
||||||
|
## 计划内缺口
|
||||||
|
- **Task 8 Step 1-2 自检与速度基线**:延后到用户 manual 验证。
|
||||||
|
- **Task 8 Step 3 真机连测**:延后到 W3。
|
||||||
|
- **Task 10 Step 2 §8 状态更新**:已在本 retro commit 内一起完成。
|
||||||
|
|
||||||
|
## 学到的
|
||||||
|
1. **`SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor` 会把跨边界类型/方法都默认推到 MainActor**,跟 actor (如 AIRuntime) 互操作时必须显式 `nonisolated` 整条调用链。`@unchecked Sendable` 不自动解锁实例方法的 isolation。
|
||||||
|
2. **iOS Simulator app sandbox 阻止读 Mac 用户目录**,集成测试无法直接验证真实推理;Mac Designed for iPad 又卡 code signing。W3 把 LLM 接口拆 SPM target 后才能写 host-fs 集成测试。
|
||||||
|
3. **`Device.withDefaultDevice` 是 TaskLocal,跨 actor 传递正常**,但跨 Task(如 AsyncStream 的 detached Task)需要在 inner Task 内重新 `withDefaultDevice`。
|
||||||
|
4. **MLX Swift API 比 mlx-swift-examples 文档稳定**,真正卡的是 Swift 6 并发系统,不是 MLX 本身。
|
||||||
|
|
||||||
|
## 下周(W3)前置准备
|
||||||
|
- [ ] 用户在 macOS App 内点 DebugAIRunner,把实际 tok/s 填进本 retro 的"速度基线"段
|
||||||
|
- [ ] 准备 5–10 张真实化验单照片(W4 VL 回归测用),放进 ~/tiji-models/test-reports/
|
||||||
|
- [ ] 准备 20 条危险问句(W3 末医疗话术安全测试)
|
||||||
|
- [ ] 决定是否把 LLM 接口拆 SPM target(便于真实推理集成测试)
|
||||||
|
- [ ] W3 plan 周一动笔,把 Symptom + Timeline 写进 spec
|
||||||
Reference in New Issue
Block a user