From 33981b909d0e0520f6a62d680b5a524868a1e053 Mon Sep 17 00:00:00 2001 From: garrytan Date: Tue, 13 Oct 2026 02:16:48 +0000 Subject: [PATCH] ci(paid-pr-profile): the vendored Capy skill is free-only; free-only files are not prompts needing paid coverage Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- scripts/test-pr-profile.ts | 2 ++ test/test-pr-profile.test.ts | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/scripts/test-pr-profile.ts b/scripts/test-pr-profile.ts index 4ae0a4525..d95cffbf2 100644 --- a/scripts/test-pr-profile.ts +++ b/scripts/test-pr-profile.ts @@ -210,6 +210,7 @@ export const FREE_ONLY_PR_FILES = [ 'scripts/free-test-durations.json', 'scripts/paid-test-durations.json', 'scripts/ubicloud/**', + 'capy/skill/**', // The vendored Capy skill (Drive bootstrapper): run by Capy agents, read by no paid case; test/capy-skill-wrapper.test.ts covers it. 'tsconfig.test.json', // Read only by `tsc -p tsconfig.test.json` (typecheck:test); Bun's runtime reads tsconfig.json. '.gitignore', // Changes which untracked files git reports, never tracked content a case reads. '.gstack/generated.json', // gstack's own regen registry: gstack-regen/gstack-pregate read it from origin/ of the repo they run in; paid cases run in fixture repos. @@ -314,6 +315,7 @@ export function packageChangeOnlyVersion(before: string, after: string): boolean } function isPromptFile(file: string): boolean { + if (FREE_ONLY_PR_FILES.some(pattern => matchGlob(file, pattern))) return false; return file.endsWith('.tmpl') || /(?:^|\/)SKILL\.md$/.test(file) || /^[^/]+\/sections\/.+\.md$/.test(file); } diff --git a/test/test-pr-profile.test.ts b/test/test-pr-profile.test.ts index 8ff78e558..d7c1219c3 100644 --- a/test/test-pr-profile.test.ts +++ b/test/test-pr-profile.test.ts @@ -51,6 +51,16 @@ describe('fast PR coverage policy', () => { expect(result.needsFullValidation).toBe(false); }); + test('the vendored Capy skill (capy/skill/**) is free-only: no paid case reads it, so it needs no full validation', () => { + const result = select({ selectedE2E: [], selectedJudges: [], changedFiles: ['capy/skill/gstack/SKILL.md', 'capy/skill/gstack/scripts/install.sh'], derived: null }); + expect(result.needsFullValidation).toBe(false); + expect(result.missingCoverage).toEqual([]); + expect(result.mode).toBe('pr'); + expect(result.e2e).toEqual([]); + const prompt = select({ selectedE2E: [], selectedJudges: [], changedFiles: ['plan-ceo-review/SKILL.md.tmpl'], derived: null }); + expect(prompt.needsFullValidation || prompt.deferredPromptFiles.length > 0 || prompt.e2e.length > 0).toBe(true); + }); + test('does not add unrelated short probes or drop selected quality judges', () => { const result = select({ selectedJudges: ['browse quality', 'plan-ceo-review/SKILL.md modes'] }); expect(result.e2e).not.toContain('browse-smoke');