From 505b85cd0d8eddd91c38a86fb3392294cd954520 Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 8 Sep 2026 00:12:30 -0700 Subject: [PATCH] fix(skills): stop asserting readdir order in the skill root walk test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Windows skill-sharing release gate — which blocks publish-release — failed on this test, wedging the 1.4.198 cut. The implementation is correct; the assertion was not. `findSkillFiles` pushes results in `readdir` order and dedupes visited directories by realpath, so of the 32 junctions pointing at one target exactly one survives. The assertion hardcoded both the array order and which link won. `readdir` order is filesystem-dependent: APFS and ext4 return SKILL.md first, while NTFS enumerates its filename index alphabetically on the uppercased name, where "LINK00" sorts before "SKILL.MD" (L=0x4C < S=0x53). Windows therefore returned the same two paths in the opposite order. Assert the contract instead: the real file is present, exactly one link-routed path survives dedup, and nothing else does. (cherry picked from commit 9a832e9bda4aaa98c04efa75e3265a2baf77ad75) --- src/main/skills/skill-root-file-walk.test.ts | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/main/skills/skill-root-file-walk.test.ts b/src/main/skills/skill-root-file-walk.test.ts index ad84eced6b6..e40462edcf7 100644 --- a/src/main/skills/skill-root-file-walk.test.ts +++ b/src/main/skills/skill-root-file-walk.test.ts @@ -66,10 +66,17 @@ describe('findSkillFiles', () => { expect(await findSkillFiles(root, 4)).toEqual([join(edge, 'SKILL.md')]) expect(statPaths).toEqual([]) - expect(await findSkillFiles(root, 5)).toEqual([ - join(edge, 'SKILL.md'), - join(edge, 'link00', 'SKILL.md') - ]) + // Why not a fixed array: `readdir` order is filesystem-dependent, and both + // the result order and which link survives dedup follow it. NTFS enumerates + // its name index alphabetically, so `link00` precedes `SKILL.md` on Windows + // and follows it on APFS/ext4. All 32 links share one realpath, so the + // visited set collapses them to a single entry beside the real file. + const withinDepth = await findSkillFiles(root, 5) + expect(withinDepth).toContain(join(edge, 'SKILL.md')) + expect(withinDepth.filter((path) => /[\\/]link\d{2}[\\/]SKILL\.md$/.test(path))).toHaveLength( + 1 + ) + expect(withinDepth).toHaveLength(2) expect(statPaths).toHaveLength(32) })