From 5aa7765c9ffc94e40c3a870887f061926daefb8a Mon Sep 17 00:00:00 2001 From: garrytan Date: Tue, 27 Oct 2026 05:58:26 +0000 Subject: [PATCH] test(auq): planted skill fixtures resolve the shared preamble like an install (GSTA-96) Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- test/helpers/auq-native-capture.ts | 2 +- test/helpers/auq-sdk-capture.ts | 10 ++++++---- test/skill-e2e-plan-format.test.ts | 7 +++++-- test/skill-e2e-plan-prosons.test.ts | 7 +++++-- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/test/helpers/auq-native-capture.ts b/test/helpers/auq-native-capture.ts index 80cbe8d6c..ba70bb8c4 100644 --- a/test/helpers/auq-native-capture.ts +++ b/test/helpers/auq-native-capture.ts @@ -303,7 +303,7 @@ export async function captureNativeFirstAuq(opts: NativeAuqCaptureOptions): Prom trustedDirs: [cwd], })), {mode:0o600}); const skillPath = path.join(cwd, opts.skillName, 'SKILL.md'); - const prompt = `The ONLY skill file you may read is this absolute path: ${skillPath}. Do NOT search for, Glob, find, or read any other SKILL.md anywhere — especially nothing under ~/.claude or /Users. + const prompt = `The ONLY skill file you may read is this absolute path: ${skillPath}, together with the files in its sections/ directory that it tells you to Read. Do NOT search for, Glob, find, or read any other SKILL.md anywhere — especially nothing under ~/.claude or /Users. Read ${skillPath} and follow its workflow for this scenario: diff --git a/test/helpers/auq-sdk-capture.ts b/test/helpers/auq-sdk-capture.ts index 116da838d..7f941ffbb 100644 --- a/test/helpers/auq-sdk-capture.ts +++ b/test/helpers/auq-sdk-capture.ts @@ -129,7 +129,8 @@ export function setupPlanCeoDir(opts: { ].join('\n'), ); fs.mkdirSync(path.join(dir, 'plan-ceo-review'), { recursive: true }); - fs.writeFileSync(path.join(dir, 'plan-ceo-review', 'SKILL.md'), opts.skillMd); + fs.writeFileSync(path.join(dir, 'plan-ceo-review', 'SKILL.md'), + opts.skillMd.replaceAll('~/.claude/skills/gstack/plan-ceo-review/sections/', path.join(dir, 'plan-ceo-review', 'sections') + '/')); if (opts.sectionsFrom && fs.existsSync(opts.sectionsFrom)) { fs.cpSync(opts.sectionsFrom, path.join(dir, 'plan-ceo-review', 'sections'), { recursive: true }); } @@ -161,7 +162,8 @@ export function setupSkillDir(opts: { fs.writeFileSync(p, content); } fs.mkdirSync(path.join(dir, opts.skillName), { recursive: true }); - fs.writeFileSync(path.join(dir, opts.skillName, 'SKILL.md'), opts.skillMd); + fs.writeFileSync(path.join(dir, opts.skillName, 'SKILL.md'), + opts.skillMd.replaceAll(`~/.claude/skills/gstack/${opts.skillName}/sections/`, path.join(dir, opts.skillName, 'sections') + '/')); if (opts.sectionsFrom && fs.existsSync(opts.sectionsFrom)) { fs.cpSync(opts.sectionsFrom, path.join(dir, opts.skillName, 'sections'), { recursive: true }); } @@ -467,11 +469,11 @@ export async function captureModeSelectionAuq(opts: { // which silently invalidates a carved-vs-verbose A/B (both sides end up // reading the same global skill). Absolute path + no-wander instruction + // Bash disallowed (so `find /` is impossible) locks it to the planted file. - const prompt = `Review the plan using ONLY these two files: + const prompt = `Review the plan with this skill and plan: - The skill to follow: ${skillPath} - The plan to review: ${planPath} -Read ${skillPath} for the review workflow. Do NOT search for, Glob, find, or read any OTHER SKILL.md anywhere on the system — especially nothing under ~/.claude or /Users. The ONLY skill file you may read is the absolute path above. +Read ${skillPath} for the review workflow. Do NOT search for, Glob, find, or read any OTHER SKILL.md anywhere on the system — especially nothing under ~/.claude or /Users. The ONLY SKILL.md you may read is the absolute path above; the files in its sections/ directory that it tells you to Read are part of this skill. Read ${planPath} — that is the plan to review. It is a standalone plan document, not a codebase. Skip any codebase exploration or system-audit steps. diff --git a/test/skill-e2e-plan-format.test.ts b/test/skill-e2e-plan-format.test.ts index e6de913bc..a2edd8360 100644 --- a/test/skill-e2e-plan-format.test.ts +++ b/test/skill-e2e-plan-format.test.ts @@ -96,10 +96,13 @@ function setupPlanDir(tmpPrefix: string, skillName: 'plan-ceo-review' | 'plan-en run('git', ['commit', '-m', 'add plan']); fs.mkdirSync(path.join(planDir, skillName), { recursive: true }); - fs.copyFileSync( - path.join(ROOT, skillName, 'SKILL.md'), + const sections = path.join(planDir, skillName, 'sections'); + fs.writeFileSync( path.join(planDir, skillName, 'SKILL.md'), + fs.readFileSync(path.join(ROOT, skillName, 'SKILL.md'), 'utf-8') + .replaceAll(`~/.claude/skills/gstack/${skillName}/sections/`, sections + '/'), ); + fs.cpSync(path.join(ROOT, skillName, 'sections'), sections, { recursive: true }); return planDir; } diff --git a/test/skill-e2e-plan-prosons.test.ts b/test/skill-e2e-plan-prosons.test.ts index 7100850d0..8c08df127 100644 --- a/test/skill-e2e-plan-prosons.test.ts +++ b/test/skill-e2e-plan-prosons.test.ts @@ -126,10 +126,13 @@ function setupPlanDir(tmpPrefix: string, planContent: string, skillName: string) run('git', ['commit', '-m', 'add plan']); fs.mkdirSync(path.join(planDir, skillName), { recursive: true }); - fs.copyFileSync( - path.join(ROOT, skillName, 'SKILL.md'), + const sections = path.join(planDir, skillName, 'sections'); + fs.writeFileSync( path.join(planDir, skillName, 'SKILL.md'), + fs.readFileSync(path.join(ROOT, skillName, 'SKILL.md'), 'utf-8') + .replaceAll(`~/.claude/skills/gstack/${skillName}/sections/`, sections + '/'), ); + fs.cpSync(path.join(ROOT, skillName, 'sections'), sections, { recursive: true }); return planDir; }