From 35805ad3c957560781f4262bacad1d4769e119c4 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Fri, 4 Sep 2026 17:58:37 +0000 Subject: [PATCH] test: the two remaining linker harnesses extract the ownership helpers; the marker is the one allowed dotfile setup-claude-skill-assets and user-render-out-dir-install slice link_claude_skill_dirs out of setup without the helpers it now calls, so the extracted function died with "command not found" (or, inside an if, degraded into "foreign, skipped"). Both harnesses now carry the full helper set and the globals. The hidden-files census allows .gstack-owned, which the linker writes for directories it creates rather than copying from the skill source. Co-Authored-By: Claude Fable 5.1 --- test/setup-claude-skill-assets.test.ts | 20 ++++++++++++++++++-- test/user-render-out-dir-install.test.ts | 13 +++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/test/setup-claude-skill-assets.test.ts b/test/setup-claude-skill-assets.test.ts index 2599a0b6d..c563b6ef5 100644 --- a/test/setup-claude-skill-assets.test.ts +++ b/test/setup-claude-skill-assets.test.ts @@ -66,6 +66,19 @@ beforeAll(() => { extractFn('_link_or_copy'), extractFn('_print_windows_copy_note_once'), extractFn('_link_skill_runtime_assets'), + extractFn('_gstack_link_target_abs'), + extractFn('_gstack_target_is_ours'), + extractFn('_gstack_generated_header'), + extractFn('_claude_entry_owned_strongly'), + extractFn('_claude_entry_is_ours'), + extractFn('_write_owned_marker'), + extractFn('_backup_skill_md'), + extractFn('_cleanup_weak_dir'), + extractFn('_gstack_dir_only_links'), + extractFn('_cleanup_linked_dir'), + '_FOREIGN_SKIPPED_ENTRIES=()', + '_BACKED_UP_SKILL_MDS=()', + `_SKILL_BACKUP_ROOT="${os.tmpdir()}/gstack-harness-backups-${process.pid}"`, extractFn('link_claude_skill_dirs'), `link_claude_skill_dirs "${ROOT}" "${installDir}"`, ].join('\n'); @@ -138,11 +151,14 @@ describe('link_claude_skill_dirs installs every runtime asset (#2317, #2454)', ( } }); - test('hidden files are not installed', () => { + test('hidden files are not installed (gstack\'s own provenance marker is the one allowed dotfile)', () => { for (const skill of installedSkillDirs()) { const hidden = fs .readdirSync(path.join(installDir, skill)) - .filter((e) => e.startsWith('.')); + .filter((e) => e.startsWith('.')) + // .gstack-owned is written by the linker for directories it creates (#2119), + // not copied from the skill source; every other dotfile must stay out. + .filter((e) => e !== '.gstack-owned'); expect(hidden).toEqual([]); } }); diff --git a/test/user-render-out-dir-install.test.ts b/test/user-render-out-dir-install.test.ts index 02e20d79a..0295c5925 100644 --- a/test/user-render-out-dir-install.test.ts +++ b/test/user-render-out-dir-install.test.ts @@ -175,6 +175,19 @@ describe('link_claude_skill_dirs prefers rendered SKILL.md (behavior)', () => { extractFn(SETUP_SRC, '_link_or_copy'), extractFn(SETUP_SRC, '_print_windows_copy_note_once'), extractFn(SETUP_SRC, '_link_skill_runtime_assets'), + extractFn(SETUP_SRC, '_gstack_link_target_abs'), + extractFn(SETUP_SRC, '_gstack_target_is_ours'), + extractFn(SETUP_SRC, '_gstack_generated_header'), + extractFn(SETUP_SRC, '_claude_entry_owned_strongly'), + extractFn(SETUP_SRC, '_claude_entry_is_ours'), + extractFn(SETUP_SRC, '_write_owned_marker'), + extractFn(SETUP_SRC, '_backup_skill_md'), + extractFn(SETUP_SRC, '_cleanup_weak_dir'), + extractFn(SETUP_SRC, '_gstack_dir_only_links'), + extractFn(SETUP_SRC, '_cleanup_linked_dir'), + '_FOREIGN_SKIPPED_ENTRIES=()', + '_BACKED_UP_SKILL_MDS=()', + `_SKILL_BACKUP_ROOT="${os.tmpdir()}/gstack-harness-backups-${process.pid}"`, extractFn(SETUP_SRC, 'link_claude_skill_dirs'), `link_claude_skill_dirs "${src}" "${skills}"`, ].join('\n');