Skip to content

fix(macos): 将运行时生成内容排除在更新检查的认证逻辑上,避免频繁的降级到全量更新 - #893

Open
xiaoyumuxi wants to merge 7 commits into
previewfrom
codex/macos-incremental-update
Open

xiaoyumuxi wants to merge 7 commits into
previewfrom
codex/macos-incremental-update

Conversation

@xiaoyumuxi

@xiaoyumuxi xiaoyumuxi commented Sep 25, 2026 •

Copy link
Copy Markdown
Collaborator

改动摘要

  • macOS 启动 bundled JDTLS 前,将配置目录复制到按 SHA-256 命名的缓存目录,避免 Eclipse/OSGi 运行时状态修改签名 app bundle。
  • 增加运行时 bundle 不可变性守护,覆盖 macOS 生产 Swift 路径和 Windows/Tauri 语言服务缓存路径。
  • 增加 Swift 回归测试:对模拟 app 资源树中的所有文件生成文件清单和 SHA-256 快照,写入模拟 JDTLS 状态后确认 bundle 未发生变化。
  • 拒绝位于 bundle 内或经符号链接落入 bundle 的缓存路径,并覆盖通过 bundle 外符号链接启动 JDTLS 的场景。
  • 在 AGENTS.md、Agent Note 决策记录和 Sparkle 更新文档中记录运行时只读边界。
  • 同步更新跨平台功能矩阵及生成视图。

根因

之前 JDTLS 直接使用 Contents/Resources/LanguageServers/jdtls/config_mac*。Eclipse/OSGi 状态会因此写入已安装的 app bundle。Sparkle 增量包基于干净发布归档生成,应用到已经被运行时修改的安装目录时会出现 Source doesn't have expected hash,随后只能回退下载完整 ZIP。

修复提交

  • 159ffdad:保持运行时 bundle 不可变。
  • fad5c2ef:补充平台功能矩阵记录。
  • b81f482f:拒绝 bundle 内的 JDTLS 缓存目标。
  • cfe73c19:正确处理通过符号链接命中的 bundled JDTLS。
  • cd442587:修正符号链接回归测试的唯一路径。

验证

  • ./.agents/skills/write-stable-tests/scripts/verify-test-stability.sh --base origin/preview --head HEAD
  • ./.agents/skills/write-stable-tests/scripts/test-stability-macos.sh -- --filter 'macJdtlsResolverSelectsDirectLaunchResourcesDeterministically'
  • ./scripts/verify-runtime-bundle-immutability.sh
  • ./scripts/verify-agent-notes.sh
  • ./scripts/verify-platform-feature-matrix.sh
  • git diff --check

以上本地校验均已通过。拆分分支前,等价实现已通过完整 macOS 测试套件。origin/preview 基线下的 scripts/test-classify-ci-changes.sh 仍受 macOS Bash 3 不支持 ${path,,} 语法影响;本 PR 对分类器的改动仅用于注册新的 macOS 发布守护检查。

@ghfind-review ghfind-review Bot added the review: high ghfind author score; see https://ghfind.com label Sep 25, 2026
@xiaoyumuxi

Copy link
Copy Markdown
Collaborator Author

审查问题 1

[P1] 拒绝位于 JDTLS bundle 内的配置缓存路径

macos/Sources/Lithe/Platform/MacOS/Runtime/MacJDTLSLaunchResourceResolver.swift:91-104

  • 实际影响: writableConfigurationDirectory 直接信任传入的 configurationCacheDirectoryURL。如果调用方传入 Bundle.main.resourceURL/LanguageServers/jdtls 或其子路径,resolver 会把配置复制回签名 app bundle,JDTLS 随后写入 OSGi 状态,重新导致 Sparkle 增量包哈希校验失败。
  • 触发条件: bundled JDTLS 解析时,缓存路径位于 bundledJdtlsRootURL 内;当前组件没有做路径边界校验。
  • 复现方式: 使用完整 fixture 构造 MacJDTLSLaunchResourceResolver(bundledJdtlsRootURL: root, configurationCacheDirectoryURL: root),调用 resolve(for: root.appendingPathComponent("bin/jdtls")),返回的配置目录会落在 root 内。
  • 来源: 本 PR 引入。
  • 修复方向: 在创建和复制目录前拒绝落入 bundle 的缓存路径,并增加测试确认拒绝时 bundle 文件清单和 SHA-256 不变。

@xiaoyumuxi

Copy link
Copy Markdown
Collaborator Author

审查问题 2

[P1] 根据实际解析到的安装根目录判断是否为 bundled 资源

macos/Sources/Lithe/Platform/MacOS/Runtime/MacJDTLSLaunchResourceResolver.swift:68-70, 222-225

  • 实际影响: 缓存迁移原先根据 isBundled(executableURL) 判断,但 installationRoots(for:) 同时会解析符号链接。若 bundle 外的启动器符号链接指向 bundle 内的 JDTLS,resolver 会命中 bundle 根目录,却把它当成 external,返回原始 config_mac* 目录;JDTLS 仍可能写入签名 bundle。
  • 触发条件: bundled JDTLS 通过 bundledJdtlsRootURL 外部的符号链接或别名启动。
  • 复现方式: 创建 bundle 外的 bin/jdtls 符号链接指向 root/bin/jdtls,再解析该链接;原实现会返回 root/config_mac*,而不是缓存副本。
  • 来源: 本 PR 新增的缓存判断逻辑。
  • 修复方向: 将实际命中的 installation root 传入缓存判断,同时解析符号链接,并增加对应回归测试。

@xiaoyumuxi

Copy link
Copy Markdown
Collaborator Author

修复结果

已在以下提交中修复上述问题:

  • b81f482f:拒绝 bundle 内的缓存目标,并验证错误目标不会改变 bundle 快照。
  • cfe73c19:根据实际 installation root 和符号链接解析结果判断 bundled 状态。
  • cd442587:修正符号链接测试使用 UUID 唯一路径。

本地验证已通过:

  • macOS focused timing test
  • test stability 校验
  • runtime bundle 不可变性校验
  • Agent Note 校验
  • 平台功能矩阵校验
  • git diff --check

@xiaoyumuxi xiaoyumuxi left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审核结论

基于 cd442587c028c741d91494714c59cadc26c6e4d4 审查完整 diff、resolver 完整实现和新增回归测试。将 JDTLS 可变状态移出发行资源的方向正确,但建议合并前修复以下两处 P2 问题(见 inline):

  1. 不完整缓存已存在时,原子发布冲突被当成“其他启动已成功填充”,最终仍返回缺少 config.ini 的目录。
  2. 只校验传入的缓存根,而不是最终写入路径;同时所谓 bundle 根实际是 JDTLS 子目录。缓存子目录符号链接和 app bundle 的其他位置仍能绕过这条只读边界。

建议分别补充“不完整目标目录后重新解析”和“缓存根在外部、子目录符号链接指向 bundle”的确定性测试;安全性测试应使用包含 Contents/Resources/LanguageServers/jdtls 及同级资源目录的完整模拟 app 结构。

验证边界

本轮为静态审查,未运行 Swift/macOS/JDTLS。查询当前 head 的 Actions 时,macOS CI 尚在运行、macOS Plugin CI 排队,其余返回的工作流已成功,因此不能将旧提交/拆分前分支的通过记录当作本 head 的完整验收。本次仅提交 Review 评论,不执行批准或合并。

Comment thread macos/Sources/Lithe/Platform/MacOS/Runtime/MacJDTLSLaunchResourceResolver.swift Outdated
@xiaoyumuxi xiaoyumuxi changed the title fix(macos): keep runtime bundle immutable for delta updates fix(macos): 将运行时生成内容排除在更新检查的认证逻辑上,避免频繁的降级到全量更新 Sep 26, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: high ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants