Commit Graph

4 Commits

Author SHA1 Message Date
link2026
acfdaa1f4f fix(concurrency): nonisolated(unsafe) static shared + 修同 actor 内冗余 await
项目开启了 -default-isolation=MainActor upcoming feature,导致:

1. static let shared 默认被视为 MainActor 隔离,即使 class 标了
   @unchecked Sendable,从其他 actor(如 AIRuntime)同步访问仍报
   "Expression is 'async' but is not marked with 'await'".

   修法:ModelStore.shared 和 FileVault.shared 都加 nonisolated(unsafe)
   修饰,明确"任何隔离上下文都可同步访问"。

2. AIRuntime.generate() 内的 Task { ... } 继承 AIRuntime actor 隔离,
   self.recordRate 是同 actor 内部调用,不需要 await,否则报
   "No 'async' operations occur within 'await' expression".

   修法:去掉冗余的 await。

** BUILD SUCCEEDED ** 已验证。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 17:00:30 +08:00
link2026
ef0fbeac97 fix(ai,persistence): ModelStore + FileVault 标 @unchecked Sendable
Xcode 26 默认开启 Swift 6 严格并发检查。AIRuntime(actor)
调用 ModelStore.shared.isReady(...) 跨 actor 边界,因 ModelStore
非 Sendable 而编译报错"Expression is 'async' but is not marked
with 'await'; this is an error in the Swift 6 language mode"。

两个类的内部状态只读(rootURL: let),方法只做线程安全的
filesystem I/O,符合 Sendable 语义,标 @unchecked Sendable
即可,不必加锁或重构。

修复目标错误:
- AIRuntime.swift:48 - guard ModelStore.shared.isReady(.llm) ...
- 后续 CaptureService 调 FileVault.shared.writeJPEG 同样路径

不影响:
- HomeView/B5ResultView 里 Text "+" 的 macOS 26.0 deprecation 是
  warning,不阻塞 build,留待 UI polish 周清理

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 16:00:47 +08:00
link2026
0739ccea2b harden(persistence): FileVault path traversal guard + error unification
按 code quality review 反馈(P0 + 4×P1):
- 加 resolveSafePath() 拒绝 / 和 .. 并验证 hasPrefix(rootURL)
- loadImage/remove 统一抛 FileVaultError(readFailed/removeFailed)
- 删除测试 struct 上多余的 @MainActor
- 每个 @Test 加 defer cleanup,不泄漏 temp 目录
- 测试图片改用生成 16x16 红色,不依赖 SF Symbol

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 15:06:49 +08:00
link2026
d704a9eb78 feat(persistence): add FileVault with complete file protection
按 W2 plan Task 3 落地原图加密存储:
- writeJPEG / loadImage / remove / wipe 四个核心操作
- Application Support/Vault/ 目录全程 .completeFileProtection
- 文件写入用 .completeFileProtection options(双保险)
- FileVault(rootURL:) 注入便于测试隔离
- shared 单例用真实 App Support 路径

测试 3 条:roundtrip / remove / wipe。

注:.swift 文件需用户在 Xcode 拖入 target(Persistence group + 体己Tests),
之后 ⌘U 跑测试,若全绿再 amend 提交 .pbxproj。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 15:03:15 +08:00