diff --git a/test/gh-aw-quality.test.ts b/test/gh-aw-quality.test.ts index 1b90c9142..db6e7dfce 100644 --- a/test/gh-aw-quality.test.ts +++ b/test/gh-aw-quality.test.ts @@ -480,3 +480,52 @@ describe('gh-aw: workflow frontmatter schema', () => { expect(frontmatter).toMatch(/allowed:/m); }); }); + +// --------------------------------------------------------------------------- +// Test: Prompt Budget & Planning Import Regression (#1684) +// --------------------------------------------------------------------------- + +describe('gh-aw: prompt budget & planning import regression', () => { + const frontmatter = extractFrontmatter(SQUAD_WORKFLOW); + const imports = extractImports(frontmatter); + const squadContent = readFileSync(SQUAD_WORKFLOW, 'utf8'); + + // gh-aw enforces a hard 100 KB prompt ceiling (102 400 bytes) + const GH_AW_PROMPT_CEILING_KB = 100; + const GH_AW_PROMPT_CEILING_BYTES = GH_AW_PROMPT_CEILING_KB * 1024; + + it('planning-ontology.md is in the imports list', () => { + expect(imports, 'shared/planning-ontology.md must be imported').toContain('shared/planning-ontology.md'); + }); + + it('planning-policy.md is in the imports list', () => { + expect(imports, 'shared/planning-policy.md must be imported').toContain('shared/planning-policy.md'); + }); + + it('no runtime cat of planning files remains in squad.md', () => { + expect( + squadContent, + 'squad.md must not contain runtime `cat .github/workflows/shared/planning-*.md` instructions' + ).not.toMatch(/cat .github\/workflows\/shared\/planning-[\w-]+\.md/); + }); + + it(`combined prompt (workflow + all imports) is under ${GH_AW_PROMPT_CEILING_KB} KB`, () => { + let totalBytes = Buffer.byteLength(squadContent, 'utf8'); + + for (const importPath of imports) { + const fullPath = join(WORKFLOWS_DIR, importPath); + if (existsSync(fullPath)) { + const content = readFileSync(fullPath, 'utf8'); + totalBytes += Buffer.byteLength(content, 'utf8'); + } + } + + const totalKB = (totalBytes / 1024).toFixed(1); + const headroomKB = ((GH_AW_PROMPT_CEILING_BYTES - totalBytes) / 1024).toFixed(1); + + expect( + totalBytes, + `Combined prompt is ${totalKB} KB — exceeds the gh-aw ${GH_AW_PROMPT_CEILING_KB} KB ceiling. Headroom: ${headroomKB} KB.` + ).toBeLessThan(GH_AW_PROMPT_CEILING_BYTES); + }); +}); diff --git a/workflows/squad.md b/workflows/squad.md index dd0cfeff7..d817ae76e 100644 --- a/workflows/squad.md +++ b/workflows/squad.md @@ -27,6 +27,8 @@ network: - defaults imports: - shared/squad.md + - shared/planning-ontology.md + - shared/planning-policy.md tools: bash: true github: @@ -412,7 +414,7 @@ Classify research findings as work/decision/excluded. Bridge between research an **TASK:** Steps 1–4. Deliverable = Step 3. -**First:** `cat .github/workflows/shared/planning-ontology.md` to load planning schemas. +The planning ontology is imported — follow its schemas directly. ##### Step 1: Validate @@ -456,7 +458,7 @@ Find/create `` comment. Set Triage = `✅ Done`, s All planning modes resolve policy before executing. -**First:** `cat .github/workflows/shared/planning-policy.md` to load the policy schema. +The planning policy schema is imported — follow it directly. Steps: 1. Check issue body for `` or ``. @@ -474,7 +476,7 @@ High-level program plan (the WHAT). Transforms triage work items into initiative **Acknowledge:** `🤖 Squad is building the program plan…` -**First:** `cat .github/workflows/shared/planning-ontology.md` to load planning schemas. +The planning ontology is imported — follow its schemas directly. ##### Step 1: Validate @@ -535,7 +537,7 @@ Decompose program plan into PR-sized tasks with deps, sizing, agent assignments. **Acknowledge:** `🤖 Squad is building the implementation plan…` -**First:** `cat .github/workflows/shared/planning-ontology.md` to load planning schemas. +The planning ontology is imported — follow its schemas directly. **TASK:** Steps 1–5. Deliverable = Step 4. @@ -571,7 +573,7 @@ Readiness gate checking plan artifacts for structural issues. **Acknowledge:** `🤖 Squad is validating the plan…` -**First:** `cat .github/workflows/shared/planning-ontology.md` to load planning schemas. +The planning ontology is imported — follow its schemas directly. **TASK:** Steps 1–5. Deliverable = Step 3.