Skip to content

[Bug] Windows 开发环境两例:check:pi-* 误报 patched 实例;native fork 测试路径断言失败 #1361

Description

@shabhui

What happened? / 问题描述

两处 Windows-only 的开发环境问题(Linux CI 均不触发):

1. check:pi-dependencies / check:pi-patches 在 Windows 上误报

node scripts/check-pi-dependencies.mjs
→ <pkg> does not resolve to pnpm's patched package instance

node scripts/check-pi-patches.mjs
→ <pkg>@1.0.0 installed patch hash is absent from pnpm-lock.yaml

两个脚本都用 realpathSync(...) 的结果里是否含字面 patch_hash= 段来判断「装的是 pnpm 的 patched 实例」(check-pi-dependencies.mjs 的 resolved.includes("patch_hash=")、check-pi-patches.mjs 的 resolved.match(/patch_hash=([a-f0-9]+)/))。但 pnpm 在 Windows 上会缩短 .pnpm 目录名(长路径限制),realpath 结果不再包含 patch_hash= 字面段 → 断言失败。

建议改用虚拟店 lockfile(node_modules/.pnpm/lock.yaml)作证据:其 snapshot key 保留完整的 'name@version(patch_hash=<64hex>' 键,能证明解析到的实例就是 patched 包,且比 realpath 字符串匹配更严格(Linux 行为不变)。本机已按此思路修复并验证通过,需要的话可以提 PR。

2. native-pi-session.test.ts 一个 fork 测试在 Windows 上失败

FAIL src/native-pi-session.test.ts > native fork children >
never deletes a foreign publication and classifies the failure path-free
AssertionError: expected [ …(2) ] to deeply equal [ …(2) ]
- Expected: "D:\\...\\--project--\\2026-…jsonl"   (整条绝对路径)
+ Received: "2026-…jsonl"                        (readdirSync 返回的文件名)

packages/agent-runtime/src/native-pi-session.test.ts L784:

expect(groupEntries(f.group).sort()).toEqual(before.concat([foreignPath.split("/").at(-1)!]).sort());

foreignPath.split("/") 按 POSIX 分隔符切路径;Windows 路径分隔符是 \,切不开,.at(-1) 返回整条绝对路径,与 readdirSync 返回的文件名比较必然失败。建议改用 path.basename(foreignPath)。

App version / 应用版本

main(check:pi-* 为 Pi 1.0.0 升级引入的脚本;测试断言在更早版本即如此)

OS

Windows

Activity

  1. yexisu commented on Oct 4, 2026

    @yexisu
    Contributor

    已提 PR:#1370(基于最新 main c79b6ca56),两例都已修复:

    例 1(check:pi- 误报)*:按你建议的思路,但走得更严格一点——不只查虚拟店 lockfile 里的 patch_hash= 字样,而是做两段式证据链:

    1. 根 pnpm-lock.yaml 的 patchedDependencies 段声明 name@version 对应的 64 位哈希;
    2. node_modules/.pnpm/lock.yaml(虚拟店 lockfile)的已安装 snapshot version: <v>(patch_hash=<hash>) 行必须嵌入该哈希。

    两段都对上才认定装的是 patched 实例。realpath 结果仍用于直接校验已安装 manifest 的版本号。这样在 Windows 缩短目录名后依然成立,且比原来「realpath 含 patch_hash= 字面段」的宽松匹配更严格(老匹配只看路径里有没有这个段,不校验哈希与 lockfile 一致)。

    例 2(fork 测试断言):foreignPath.split("/").at(-1)! 改为 path.basename(foreignPath)。

    验证:例 2 的测试在本机(Windows)从失败转为通过(该测试在干净 main 上确实失败,已复现);例 1 的两段式哈希链已在本机 lockfile 上验证——1.0.1 的声明哈希能正确解析出,而本机过期的 0.99.1 虚拟店 snapshot 正确地未通过嵌入校验(证明校验是严格的)。完整 check:pi-* 端到端运行需要本机完成 1.0.1 安装,其余由 CI 覆盖。

  2. added a commit that references this issue on Oct 4, 2026
  3. added a commit that references this issue on Oct 4, 2026
    51ab772
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions